From f4a2e227e1a7224fbbe9c99d9aa033d176a9c4de Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 29 Jul 2018 21:58:39 +0200 Subject: Remove all in-package monorepo-scripts by adding doc gen/upload and aggregate release note publishing to publish script --- packages/monorepo-scripts/package.json | 10 +- .../src/doc_generate_and_upload.ts | 215 +++++++++++++++++++++ packages/monorepo-scripts/src/index.ts | 1 - packages/monorepo-scripts/src/postpublish_utils.ts | 202 ------------------- packages/monorepo-scripts/src/publish.ts | 98 +++++++++- 5 files changed, 318 insertions(+), 208 deletions(-) create mode 100644 packages/monorepo-scripts/src/doc_generate_and_upload.ts delete mode 100644 packages/monorepo-scripts/src/postpublish_utils.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 128bdcff5..24f1607c0 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -17,7 +17,8 @@ "script:deps_versions": "node ./lib/deps_versions.js", "script:prepublish_checks": "node ./lib/prepublish_checks.js", "script:publish": "IS_DRY_RUN=true node ./lib/publish.js", - "script:find_unused_deps": "node ./lib/find_unused_dependencies.js" + "script:find_unused_deps": "node ./lib/find_unused_dependencies.js", + "script:doc_generate_and_upload": "node ./lib/doc_generate_and_upload.js" }, "repository": { "type": "git", @@ -38,8 +39,7 @@ "make-promises-safe": "^1.1.0", "npm-run-all": "^4.1.2", "shx": "^0.2.2", - "tslint": "5.11.0", - "typescript": "2.7.1" + "tslint": "5.11.0" }, "dependencies": { "@lerna/batch-packages": "^3.0.0-beta.18", @@ -58,7 +58,9 @@ "rimraf": "^2.6.2", "semver": "5.5.0", "semver-diff": "^2.1.0", - "semver-sort": "0.0.4" + "semver-sort": "0.0.4", + "typedoc": "0xProject/typedoc", + "typescript": "2.7.1" }, "publishConfig": { "access": "public" diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts new file mode 100644 index 000000000..b6a4801e3 --- /dev/null +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -0,0 +1,215 @@ +import { readFileSync, writeFileSync } from 'fs'; +import * as _ from 'lodash'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; +import * as ts from 'typescript'; +import * as yargs from 'yargs'; + +import { constants } from './constants'; +import { utils } from './utils/utils'; + +export interface ExportPathToExportedItems { + [pkgName: string]: string[]; +} + +const args = yargs + .option('package', { + describe: 'Monorepo sub-package for which to generate DocJSON', + type: 'string', + demandOption: true, + }) + .option('isStaging', { + describe: 'Whether we with to publish docs to staging or production', + type: 'boolean', + demandOption: true, + }) + .example("$0 --package '0x.js' --isStaging true", 'Full usage example').argv; + +(async () => { + const packageName = args.package; + const isStaging = args.isStaging; + + await generateAndUploadDocsAsync(packageName, isStaging); +})(); + +export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { + const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; + const indexPath = `${pathToPackage}/src/index.ts`; + const exportPathToExportedItems = getExportPathToExportedItems(indexPath); + + const monorepoPackages = utils.getPackages(constants.monorepoRootPath); + const pkg = _.find(monorepoPackages, monorepoPackage => { + return _.includes(monorepoPackage.packageJson.name, packageName); + }); + if (_.isUndefined(pkg)) { + throw new Error(`Couldn't find a package.json for ${packageName}`); + } + + const packageJson = pkg.packageJson; + const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); + if (!shouldPublishDocs) { + utils.log( + `GENERATE_UPLOAD_DOCS: ${ + packageJson.name + } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, + ); + return; + } + + const pkgNameToPath: { [name: string]: string } = {}; + _.each(monorepoPackages, pkg => { + pkgNameToPath[pkg.packageJson.name] = pkg.location; + }); + + // For each dep that is another one of our monorepo packages, we fetch it's index.ts + // and see which specific files we must pass to TypeDoc. + let typeDocExtraFileIncludes: string[] = []; + _.each(exportPathToExportedItems, (exportedItems, exportPath) => { + const isInternalToPkg = _.startsWith(exportPath, '.'); + if (isInternalToPkg) { + const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); + typeDocExtraFileIncludes.push(pathToInternalPkg); + } + const pathIfExists = pkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + return; // It's an external package + } + const typeDocSourceIncludes = new Set(); + const pathToIndex = `${pathIfExists}/src/index.ts`; + const innerExportPathToExportedItems = getExportPathToExportedItems(pathToIndex); + _.each(exportedItems, exportName => { + _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { + if (!_.startsWith(innerExportPath, './')) { + // noop. Not an internal export... but rather an external one. Should we follow it? + return; + } + if (_.includes(innerExportItems, exportName)) { + const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); + typeDocSourceIncludes.add(absoluteSrcPath); + } + }); + }); + // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types + // directly, meaning no internal paths will exist to follow. This, we add the index file. + // TODO: Maybe we should add the index for all packages? + if (typeDocSourceIncludes.size === 0) { + typeDocSourceIncludes.add(pathToIndex); + } + typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; + }); + + // Generate Typedoc JSON file + const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); + const projectFiles = typeDocExtraFileIncludes.join(' '); + const cwd = path.join(constants.monorepoRootPath, 'packages/0x.js/'); + // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the + // packages root dir, does not work. It only works when called via a `package.json` script located + // in the packages root. + await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { + cwd, + }); + + // For each entry, see if it was exported in index.ts. If not, remove it. + const typedocOutputString = readFileSync(jsonFilePath).toString(); + const typedocOutput = JSON.parse(typedocOutputString); + const finalTypeDocOutput = _.clone(typedocOutput); + _.each(typedocOutput.children, (file, i) => { + const exportItems = findExportItemsGivenTypedocName(exportPathToExportedItems, packageName, file.name); + // Map file "name" to exportPath... HOW?! + _.each(file.children, (child, j) => { + if (!_.includes(exportItems, child.name)) { + delete finalTypeDocOutput.children[i].children[j]; + } + }); + finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); + }); + // Write modified TypeDoc JSON, without all the unexported stuff + writeFileSync(jsonFilePath, JSON.stringify(finalTypeDocOutput, null, 2)); + + const fileName = `v${packageJson.version}.json`; + utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); + const S3BucketPath = isStaging ? `s3://staging-doc-jsons/${packageName}/` : `s3://doc-jsons/${packageName}/`; + const s3Url = `${S3BucketPath}${fileName}`; + await execAsync( + `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, + { + cwd, + }, + ); + utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); + // Remove the generated docs directory + await execAsync(`rm -rf ${jsonFilePath}`, { + cwd, + }); +} + +function findExportItemsGivenTypedocName( + exportPathToExportedItems: ExportPathToExportedItems, + packageName: string, + typedocName: string, +): string[] { + const typeDocNameWithoutQuotes = _.replace(typedocName, '"', ''); + const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; + const exportPaths = _.keys(exportPathToExportedItems); + const sanitizedExportPaths = _.map(exportPaths, exportPath => { + if (_.startsWith(exportPath, './')) { + const sanitizedExportPath = path.join(packageName, 'src', exportPath); + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + const monorepoPrefix = '@0xproject/'; + if (_.startsWith(exportPath, monorepoPrefix)) { + const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + sanitizedExportPathToExportPath[exportPath] = exportPath; + return exportPath; + }); + const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPaths, p => { + return _.startsWith(typeDocNameWithoutQuotes, p); + }); + if (_.isUndefined(matchingSanitizedExportPathIfExists)) { + throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); + } + const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; + return exportPathToExportedItems[matchingExportPath]; +} + +function getExportPathToExportedItems(pkgPath: string): ExportPathToExportedItems { + const sourceFile = ts.createSourceFile( + 'indexFile', + readFileSync(pkgPath).toString(), + ts.ScriptTarget.ES2017, + /*setParentNodes */ true, + ); + const exportPathToExportedItems = _getExportPathToExportedItems(sourceFile); + return exportPathToExportedItems; +} + +function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedItems { + const exportPathToExportedItems: ExportPathToExportedItems = {}; + processNode(sf); + + function processNode(node: ts.Node): void { + switch (node.kind) { + case ts.SyntaxKind.ExportDeclaration: + // console.log(node); + const exportClause = (node as any).exportClause; + const pkgName = exportClause.parent.moduleSpecifier.text; + _.each(exportClause.elements, element => { + exportPathToExportedItems[pkgName] = _.isUndefined(exportPathToExportedItems[pkgName]) + ? [element.name.escapedText] + : [...exportPathToExportedItems[pkgName], element.name.escapedText]; + }); + break; + + default: + // noop + break; + } + + ts.forEachChild(node, processNode); + } + return exportPathToExportedItems; +} diff --git a/packages/monorepo-scripts/src/index.ts b/packages/monorepo-scripts/src/index.ts index 95c96ebe8..e69de29bb 100644 --- a/packages/monorepo-scripts/src/index.ts +++ b/packages/monorepo-scripts/src/index.ts @@ -1 +0,0 @@ -export { postpublishUtils } from './postpublish_utils'; diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts deleted file mode 100644 index 8e445a045..000000000 --- a/packages/monorepo-scripts/src/postpublish_utils.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { execAsync } from 'async-child-process'; -import * as promisify from 'es6-promisify'; -import * as fs from 'fs'; -import * as _ from 'lodash'; -import * as path from 'path'; -import * as publishRelease from 'publish-release'; - -import { constants } from './constants'; -import { configs } from './utils/configs'; -import { utils } from './utils/utils'; - -const publishReleaseAsync = promisify(publishRelease); -const generatedDocsDirectoryName = 'generated_docs'; - -export interface PostpublishConfigs { - cwd: string; - packageName: string; - version: string; - assets: string[]; - docPublishConfigs: DocPublishConfigs; -} - -export interface DocPublishConfigs { - fileIncludes: string[]; - s3BucketPath: string; - s3StagingBucketPath: string; -} - -export const postpublishUtils = { - generateConfig(packageJSON: any, tsConfigJSON: any, cwd: string): PostpublishConfigs { - if (_.isUndefined(packageJSON.name)) { - throw new Error('name field required in package.json. Cannot publish release notes to Github.'); - } - if (_.isUndefined(packageJSON.version)) { - throw new Error('version field required in package.json. Cannot publish release notes to Github.'); - } - const postpublishConfig = _.get(packageJSON, 'config.postpublish', {}); - const postpublishConfigs: PostpublishConfigs = { - cwd, - packageName: packageJSON.name, - version: packageJSON.version, - assets: _.get(postpublishConfig, 'assets', []), - docPublishConfigs: { - fileIncludes: [ - ...tsConfigJSON.include, - ..._.get(postpublishConfig, 'docPublishConfigs.extraFileIncludes', []), - ], - s3BucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3BucketPath'), - s3StagingBucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3StagingBucketPath'), - }, - }; - return postpublishConfigs; - }, - async runAsync(packageJSON: any, tsConfigJSON: any, cwd: string): Promise { - if (configs.IS_LOCAL_PUBLISH) { - return; - } - const postpublishConfigs = postpublishUtils.generateConfig(packageJSON, tsConfigJSON, cwd); - await postpublishUtils.publishReleaseNotesAsync( - postpublishConfigs.packageName, - postpublishConfigs.version, - postpublishConfigs.assets, - ); - if ( - !_.isUndefined(postpublishConfigs.docPublishConfigs.s3BucketPath) || - !_.isUndefined(postpublishConfigs.docPublishConfigs.s3StagingBucketPath) - ) { - utils.log('POSTPUBLISH: Release successful, generating docs...'); - await postpublishUtils.generateAndUploadDocsAsync( - postpublishConfigs.cwd, - postpublishConfigs.docPublishConfigs.fileIncludes, - postpublishConfigs.version, - postpublishConfigs.docPublishConfigs.s3BucketPath, - ); - } else { - utils.log(`POSTPUBLISH: No S3Bucket config found for ${packageJSON.name}. Skipping doc JSON generation.`); - } - }, - async publishDocsToStagingAsync(packageJSON: any, tsConfigJSON: any, cwd: string): Promise { - const postpublishConfigs = postpublishUtils.generateConfig(packageJSON, tsConfigJSON, cwd); - if (_.isUndefined(postpublishConfigs.docPublishConfigs.s3StagingBucketPath)) { - utils.log('config.postpublish.docPublishConfigs.s3StagingBucketPath entry in package.json not found!'); - return; - } - - utils.log('POSTPUBLISH: Generating docs...'); - await postpublishUtils.generateAndUploadDocsAsync( - postpublishConfigs.cwd, - postpublishConfigs.docPublishConfigs.fileIncludes, - postpublishConfigs.version, - postpublishConfigs.docPublishConfigs.s3StagingBucketPath, - ); - }, - async publishReleaseNotesAsync(packageName: string, version: string, assets: string[]): Promise { - const notes = postpublishUtils.getReleaseNotes(packageName, version); - const releaseName = postpublishUtils.getReleaseName(packageName, version); - const tag = postpublishUtils.getTag(packageName, version); - postpublishUtils.adjustAssetPaths(assets); - utils.log('POSTPUBLISH: Releasing ', releaseName, '...'); - await publishReleaseAsync({ - token: constants.githubPersonalAccessToken, - owner: '0xProject', - repo: '0x-monorepo', - tag, - name: releaseName, - notes, - draft: false, - prerelease: false, - reuseRelease: true, - reuseDraftOnly: false, - assets, - }); - }, - getReleaseNotes(packageName: string, version: string): string { - const packageNameWithNamespace = packageName.replace('@0xproject/', ''); - const changelogJSONPath = path.join( - constants.monorepoRootPath, - 'packages', - packageNameWithNamespace, - 'CHANGELOG.json', - ); - const changelogJSON = fs.readFileSync(changelogJSONPath, 'utf-8'); - const changelogs = JSON.parse(changelogJSON); - const latestLog = changelogs[0]; - // We sanity check that the version for the changelog notes we are about to publish to Github - // correspond to the new version of the package. - if (version !== latestLog.version) { - throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); - } - let notes = ''; - _.each(latestLog.changes, change => { - notes += `* ${change.note}`; - if (change.pr) { - notes += ` (#${change.pr})`; - } - notes += `\n`; - }); - return notes; - }, - getTag(packageName: string, version: string): string { - return `${packageName}@${version}`; - }, - getReleaseName(subPackageName: string, version: string): string { - const releaseName = `${subPackageName} v${version}`; - return releaseName; - }, - // Asset paths should described from the monorepo root. This method prefixes - // the supplied path with the absolute path to the monorepo root. - adjustAssetPaths(assets: string[]): string[] { - const finalAssets: string[] = []; - _.each(assets, (asset: string) => { - finalAssets.push(`${constants.monorepoRootPath}/${asset}`); - }); - return finalAssets; - }, - adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] { - const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => { - let includePath = _.startsWith(fileInclude, './') - ? `${cwd}/${fileInclude.substr(2)}` - : `${cwd}/${fileInclude}`; - - // HACK: tsconfig.json needs wildcard directory endings as `/**/*` - // but TypeDoc needs it as `/**` in order to pick up files at the root - if (_.endsWith(includePath, '/**/*')) { - // tslint:disable-next-line:custom-no-magic-numbers - includePath = includePath.slice(0, -2); - } - return includePath; - }); - return fileIncludesAdjusted; - }, - async generateAndUploadDocsAsync( - cwd: string, - fileIncludes: string[], - version: string, - S3BucketPath: string, - ): Promise { - const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, cwd); - const projectFiles = fileIncludesAdjusted.join(' '); - const jsonFilePath = `${cwd}/${generatedDocsDirectoryName}/index.json`; - const result = await execAsync( - `JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, - { - cwd, - }, - ); - if (!_.isEmpty(result.stderr)) { - throw new Error(result.stderr); - } - const fileName = `v${version}.json`; - utils.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`); - const s3Url = S3BucketPath + fileName; - await execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, { - cwd, - }); - // Remove the generated docs directory - await execAsync(`rm -rf ${generatedDocsDirectoryName}`, { - cwd, - }); - utils.log(`POSTPUBLISH: Docs uploaded to S3 bucket: ${S3BucketPath}`); - }, -}; diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 5992131db..7444c64b1 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -8,12 +8,16 @@ import { exec as execAsync } from 'promisify-child-process'; import * as prompt from 'prompt'; import semver = require('semver'); import semverSort = require('semver-sort'); +import * as publishRelease from 'publish-release'; + +const publishReleaseAsync = promisify(publishRelease); import { constants } from './constants'; import { Package, PackageToNextVersion, VersionChangelog } from './types'; import { changelogUtils } from './utils/changelog_utils'; import { configs } from './utils/configs'; import { utils } from './utils/utils'; +import { generateAndUploadDocsAsync } from './doc_generate_and_upload'; const DOC_GEN_COMMAND = 'docs:json'; const NPM_NAMESPACE = '@0xproject/'; @@ -70,15 +74,27 @@ const packageNameToWebsitePath: { [name: string]: string } = { }); utils.log(`Calling 'lerna publish'...`); await lernaPublishAsync(packageToNextVersion); + const isStaging = false; + await generateAndUploadDocJsonsAsync(updatedPublicPackages, isStaging); + await publishReleaseNotesAsync(updatedPublicPackages); })().catch(err => { utils.log(err); process.exit(1); }); +async function generateAndUploadDocJsonsAsync(updatedPublicPackages: Package[], isStaging: boolean) { + for (const pkg of updatedPublicPackages) { + const packageName = pkg.packageJson.name; + const nameWithoutPrefix = packageName.replace('@0xproject/', ''); + await generateAndUploadDocsAsync(nameWithoutPrefix, isStaging); + } +} + async function confirmDocPagesRenderAsync(packages: Package[]): Promise { // push docs to staging utils.log("Upload all docJson's to S3 staging..."); - await execAsync(`yarn stage_docs`, { cwd: constants.monorepoRootPath }); + const isStaging = true; + await generateAndUploadDocJsonsAsync(packages, isStaging); // deploy website to staging utils.log('Deploy website to staging...'); @@ -178,6 +194,86 @@ async function updateChangeLogsAsync(updatedPublicPackages: Package[]): Promise< return packageToNextVersion; } +async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { + // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) + const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); + const latestGitCommit = result.stdout; + const shortenedGitCommit = latestGitCommit.slice(0, 7); + const tagName = `monorepo@${shortenedGitCommit}`; + // TODO: We might need to handle the case where the tag already exists locally + await execAsync('git tag ${tagName}'); + await execAsync('git push origin ${tagName}'); + const releaseName = `0x monorepo - ${shortenedGitCommit}`; + + let assets: string[] = []; + let aggregateNotes = ''; + _.each(updatedPublishPackages, pkg => { + const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); + aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; + + const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); + if (!_.isUndefined(packageAssets)) { + assets = [...assets, ...packageAssets]; + } + }); + adjustAssetPaths(assets); + + utils.log('PUBLISH: Releasing ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync({ + token: constants.githubPersonalAccessToken, + owner: '0xProject', + tag: tagName, + repo: '0x-monorepo', + name: releaseName, + notes: aggregateNotes, + draft: false, + prerelease: false, + reuseRelease: true, + reuseDraftOnly: false, + assets, + }); +} + +// Asset paths should described from the monorepo root. This method prefixes +// the supplied path with the absolute path to the monorepo root. +function adjustAssetPaths(assets: string[]): string[] { + const finalAssets: string[] = []; + _.each(assets, (asset: string) => { + finalAssets.push(`${constants.monorepoRootPath}/${asset}`); + }); + return finalAssets; +} + +function getReleaseNotesForPackage(packageName: string, version: string): string { + const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); + const changelogJSONPath = path.join( + constants.monorepoRootPath, + 'packages', + packageNameWithoutNamespace, + 'CHANGELOG.json', + ); + const changelogJSON = fs.readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + // We sanity check that the version for the changelog notes we are about to publish to Github + // correspond to the new version of the package. + if (version !== latestLog.version) { + throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); + } + let notes = ''; + _.each(latestLog.changes, change => { + notes += `* ${change.note}`; + if (change.pr) { + notes += ` (#${change.pr})`; + } + notes += `\n`; + }); + return notes; +} + async function lernaPublishAsync(packageToNextVersion: { [name: string]: string }): Promise { const packageVersionString = _.map(packageToNextVersion, (nextVersion: string, packageName: string) => { return `${packageName}@${nextVersion}`; -- cgit v1.2.3 From 9f7479711e64eaedbd23466f946df262f67a5097 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 29 Jul 2018 22:29:56 +0200 Subject: Improve doc gen script --- .../src/doc_generate_and_upload.ts | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index b6a4801e3..592c36ae2 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -19,7 +19,7 @@ const args = yargs demandOption: true, }) .option('isStaging', { - describe: 'Whether we with to publish docs to staging or production', + describe: 'Whether we wish to publish docs to staging or production', type: 'boolean', demandOption: true, }) @@ -65,23 +65,27 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // and see which specific files we must pass to TypeDoc. let typeDocExtraFileIncludes: string[] = []; _.each(exportPathToExportedItems, (exportedItems, exportPath) => { + const pathIfExists = pkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + return; // It's an external package + } + const isInternalToPkg = _.startsWith(exportPath, '.'); if (isInternalToPkg) { const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); typeDocExtraFileIncludes.push(pathToInternalPkg); } - const pathIfExists = pkgNameToPath[exportPath]; - if (_.isUndefined(pathIfExists)) { - return; // It's an external package - } const typeDocSourceIncludes = new Set(); const pathToIndex = `${pathIfExists}/src/index.ts`; const innerExportPathToExportedItems = getExportPathToExportedItems(pathToIndex); _.each(exportedItems, exportName => { _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { if (!_.startsWith(innerExportPath, './')) { - // noop. Not an internal export... but rather an external one. Should we follow it? - return; + throw new Error( + `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting on of ${exportedItems} which is + itself exported from an external package. To fix this, export the external dependency directly, + not indirectly through ${exportPath}.`, + ); } if (_.includes(innerExportItems, exportName)) { const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); @@ -90,21 +94,20 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); }); // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types - // directly, meaning no internal paths will exist to follow. This, we add the index file. - // TODO: Maybe we should add the index for all packages? - if (typeDocSourceIncludes.size === 0) { - typeDocSourceIncludes.add(pathToIndex); - } + // directly, meaning no internal paths will exist to follow. Other packages also have direct exports + // in their index.ts, so we always add it to the source files passed to TypeDoc + typeDocSourceIncludes.add(pathToIndex); + typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; }); // Generate Typedoc JSON file const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); const projectFiles = typeDocExtraFileIncludes.join(' '); - const cwd = path.join(constants.monorepoRootPath, 'packages/0x.js/'); + const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the // packages root dir, does not work. It only works when called via a `package.json` script located - // in the packages root. + // in the package's root. await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { cwd, }); @@ -115,7 +118,6 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: const finalTypeDocOutput = _.clone(typedocOutput); _.each(typedocOutput.children, (file, i) => { const exportItems = findExportItemsGivenTypedocName(exportPathToExportedItems, packageName, file.name); - // Map file "name" to exportPath... HOW?! _.each(file.children, (child, j) => { if (!_.includes(exportItems, child.name)) { delete finalTypeDocOutput.children[i].children[j]; -- cgit v1.2.3 From bb9237b0f41ffb484ff603a3e556919482187fbf Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 29 Jul 2018 23:01:21 +0200 Subject: Make monorepo-scripts a private package now that no other package depends on it --- packages/monorepo-scripts/package.json | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 24f1607c0..2a885e389 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,4 +1,5 @@ { + "private": true, "name": "@0xproject/monorepo-scripts", "version": "1.0.4", "engines": { -- cgit v1.2.3 From 1b24064c9f62b0b5638a5dab1878278e8e01649e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 29 Jul 2018 23:34:42 +0200 Subject: Move publish_release_notes to own script and other publish cleanup --- packages/monorepo-scripts/package.json | 3 +- packages/monorepo-scripts/src/constants.ts | 1 + packages/monorepo-scripts/src/publish.ts | 100 +------------------ .../monorepo-scripts/src/publish_release_notes.ts | 110 +++++++++++++++++++++ 4 files changed, 116 insertions(+), 98 deletions(-) create mode 100644 packages/monorepo-scripts/src/publish_release_notes.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 2a885e389..d7b83e37e 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -19,7 +19,8 @@ "script:prepublish_checks": "node ./lib/prepublish_checks.js", "script:publish": "IS_DRY_RUN=true node ./lib/publish.js", "script:find_unused_deps": "node ./lib/find_unused_dependencies.js", - "script:doc_generate_and_upload": "node ./lib/doc_generate_and_upload.js" + "script:doc_generate_and_upload": "node ./lib/doc_generate_and_upload.js", + "script:publish_release_notes": "node ./lib/publish_release_notes.js" }, "repository": { "type": "git", diff --git a/packages/monorepo-scripts/src/constants.ts b/packages/monorepo-scripts/src/constants.ts index e5d3348bd..acb4b211e 100644 --- a/packages/monorepo-scripts/src/constants.ts +++ b/packages/monorepo-scripts/src/constants.ts @@ -5,4 +5,5 @@ export const constants = { stagingWebsite: 'http://staging-0xproject.s3-website-us-east-1.amazonaws.com', lernaExecutable: path.join('node_modules', '@0x-lerna-fork', 'lerna', 'cli.js'), githubPersonalAccessToken: process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS, + dependenciesUpdatedMessage: 'Dependencies updated', }; diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 7444c64b1..faaa268fc 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -8,9 +8,6 @@ import { exec as execAsync } from 'promisify-child-process'; import * as prompt from 'prompt'; import semver = require('semver'); import semverSort = require('semver-sort'); -import * as publishRelease from 'publish-release'; - -const publishReleaseAsync = promisify(publishRelease); import { constants } from './constants'; import { Package, PackageToNextVersion, VersionChangelog } from './types'; @@ -18,22 +15,11 @@ import { changelogUtils } from './utils/changelog_utils'; import { configs } from './utils/configs'; import { utils } from './utils/utils'; import { generateAndUploadDocsAsync } from './doc_generate_and_upload'; +import { publishReleaseNotesAsync } from './publish_release_notes'; const DOC_GEN_COMMAND = 'docs:json'; const NPM_NAMESPACE = '@0xproject/'; const TODAYS_TIMESTAMP = moment().unix(); -const packageNameToWebsitePath: { [name: string]: string } = { - '0x.js': '0xjs', - 'web3-wrapper': 'web3_wrapper', - contracts: 'contracts', - connect: 'connect', - 'json-schemas': 'json-schemas', - 'sol-compiler': 'sol-compiler', - 'sol-cov': 'sol-cov', - subproviders: 'subproviders', - 'order-utils': 'order-utils', - 'ethereum-types': 'ethereum-types', -}; (async () => { // Fetch public, updated Lerna packages @@ -111,7 +97,7 @@ async function confirmDocPagesRenderAsync(packages: Package[]): Promise { _.each(packagesWithDocs, pkg => { const name = pkg.packageJson.name; const nameWithoutPrefix = _.startsWith(name, NPM_NAMESPACE) ? name.split('@0xproject/')[1] : name; - const docSegmentIfExists = packageNameToWebsitePath[nameWithoutPrefix]; + const docSegmentIfExists = nameWithoutPrefix; if (_.isUndefined(docSegmentIfExists)) { throw new Error( `Found package '${name}' with doc commands but no corresponding docSegment in monorepo_scripts @@ -163,7 +149,7 @@ async function updateChangeLogsAsync(updatedPublicPackages: Package[]): Promise< version: nextPatchVersionIfValid, changes: [ { - note: 'Dependencies updated', + note: constants.dependenciesUpdatedMessage, }, ], }; @@ -194,86 +180,6 @@ async function updateChangeLogsAsync(updatedPublicPackages: Package[]): Promise< return packageToNextVersion; } -async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { - // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) - const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); - const latestGitCommit = result.stdout; - const shortenedGitCommit = latestGitCommit.slice(0, 7); - const tagName = `monorepo@${shortenedGitCommit}`; - // TODO: We might need to handle the case where the tag already exists locally - await execAsync('git tag ${tagName}'); - await execAsync('git push origin ${tagName}'); - const releaseName = `0x monorepo - ${shortenedGitCommit}`; - - let assets: string[] = []; - let aggregateNotes = ''; - _.each(updatedPublishPackages, pkg => { - const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); - aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; - - const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); - if (!_.isUndefined(packageAssets)) { - assets = [...assets, ...packageAssets]; - } - }); - adjustAssetPaths(assets); - - utils.log('PUBLISH: Releasing ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 - await publishReleaseAsync({ - token: constants.githubPersonalAccessToken, - owner: '0xProject', - tag: tagName, - repo: '0x-monorepo', - name: releaseName, - notes: aggregateNotes, - draft: false, - prerelease: false, - reuseRelease: true, - reuseDraftOnly: false, - assets, - }); -} - -// Asset paths should described from the monorepo root. This method prefixes -// the supplied path with the absolute path to the monorepo root. -function adjustAssetPaths(assets: string[]): string[] { - const finalAssets: string[] = []; - _.each(assets, (asset: string) => { - finalAssets.push(`${constants.monorepoRootPath}/${asset}`); - }); - return finalAssets; -} - -function getReleaseNotesForPackage(packageName: string, version: string): string { - const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); - const changelogJSONPath = path.join( - constants.monorepoRootPath, - 'packages', - packageNameWithoutNamespace, - 'CHANGELOG.json', - ); - const changelogJSON = fs.readFileSync(changelogJSONPath, 'utf-8'); - const changelogs = JSON.parse(changelogJSON); - const latestLog = changelogs[0]; - // We sanity check that the version for the changelog notes we are about to publish to Github - // correspond to the new version of the package. - if (version !== latestLog.version) { - throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); - } - let notes = ''; - _.each(latestLog.changes, change => { - notes += `* ${change.note}`; - if (change.pr) { - notes += ` (#${change.pr})`; - } - notes += `\n`; - }); - return notes; -} - async function lernaPublishAsync(packageToNextVersion: { [name: string]: string }): Promise { const packageVersionString = _.map(packageToNextVersion, (nextVersion: string, packageName: string) => { return `${packageName}@${nextVersion}`; diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts new file mode 100644 index 000000000..acfac0be7 --- /dev/null +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -0,0 +1,110 @@ +import { readFileSync } from 'fs'; +import * as _ from 'lodash'; +import * as promisify from 'es6-promisify'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; +import * as publishRelease from 'publish-release'; + +import { constants } from './constants'; +import { Package } from './types'; +import { utils } from './utils/utils'; + +const publishReleaseAsync = promisify(publishRelease); + +(async () => { + console.log('I RAN! - publishReleaseNotesAsync'); + const shouldIncludePrivate = false; + const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + + await publishReleaseNotesAsync(allUpdatedPackages); +})(); + +export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { + // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) + const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); + const latestGitCommit = result.stdout; + const shortenedGitCommit = latestGitCommit.slice(0, 7); + const tagName = `monorepo@${shortenedGitCommit}`; + + await execAsync(`git rev-parse ${tagName}`); + await execAsync('git tag ${tagName}'); + + await execAsync('git push origin ${tagName}'); + const releaseName = `0x monorepo - ${shortenedGitCommit}`; + + let assets: string[] = []; + let aggregateNotes = ''; + _.each(updatedPublishPackages, pkg => { + const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); + if (_.isEmpty(notes)) { + return; // don't include it + } + aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; + + const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); + if (!_.isUndefined(packageAssets)) { + assets = [...assets, ...packageAssets]; + } + }); + const finalAssets = adjustAssetPaths(assets); + + utils.log('Publishing release notes ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync({ + token: constants.githubPersonalAccessToken, + owner: '0xProject', + tag: tagName, + repo: '0x-monorepo', + name: releaseName, + notes: aggregateNotes, + draft: false, + prerelease: false, + reuseRelease: true, + reuseDraftOnly: false, + assets: finalAssets, + }); +} + +// Asset paths should described from the monorepo root. This method prefixes +// the supplied path with the absolute path to the monorepo root. +function adjustAssetPaths(assets: string[]): string[] { + const finalAssets: string[] = []; + _.each(assets, (asset: string) => { + const finalAsset = `${constants.monorepoRootPath}/${asset}`; + finalAssets.push(finalAsset); + }); + return finalAssets; +} + +function getReleaseNotesForPackage(packageName: string, version: string): string { + const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); + const changelogJSONPath = path.join( + constants.monorepoRootPath, + 'packages', + packageNameWithoutNamespace, + 'CHANGELOG.json', + ); + const changelogJSON = readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + // If only has a `Dependencies updated` changelog, we don't include it in release notes + if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { + return ''; + } + // We sanity check that the version for the changelog notes we are about to publish to Github + // correspond to the new version of the package. + // if (version !== latestLog.version) { + // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); + // } + let notes = ''; + _.each(latestLog.changes, change => { + notes += `* ${change.note}`; + if (change.pr) { + notes += ` (#${change.pr})`; + } + notes += `\n`; + }); + return notes; +} -- cgit v1.2.3 From b7ff1fe5d352b4f59664198d9fe852cbe1015357 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 29 Jul 2018 23:34:49 +0200 Subject: Move type --- packages/monorepo-scripts/src/doc_generate_and_upload.ts | 9 +++++---- packages/monorepo-scripts/src/types.ts | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index 592c36ae2..03910c460 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -6,12 +6,9 @@ import * as ts from 'typescript'; import * as yargs from 'yargs'; import { constants } from './constants'; +import { ExportPathToExportedItems } from './types'; import { utils } from './utils/utils'; -export interface ExportPathToExportedItems { - [pkgName: string]: string[]; -} - const args = yargs .option('package', { describe: 'Monorepo sub-package for which to generate DocJSON', @@ -26,8 +23,12 @@ const args = yargs .example("$0 --package '0x.js' --isStaging true", 'Full usage example').argv; (async () => { + console.log('I RAN! - generateAndUploadDocsAsync'); const packageName = args.package; const isStaging = args.isStaging; + if (_.isEmpty(packageName)) { + return; // We are not runninng in a command-line env. + } await generateAndUploadDocsAsync(packageName, isStaging); })(); diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index d9e1dfabb..4d4600abf 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -49,3 +49,7 @@ export interface Package { location: string; packageJson: PackageJSON; } + +export interface ExportPathToExportedItems { + [pkgName: string]: string[]; +} -- cgit v1.2.3 From b56fc697c41649fdb3bdeaf9709781c9fd166b08 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 29 Jul 2018 23:55:28 +0200 Subject: Move logic to publishUtils so can use as command-line and script import --- .../src/doc_generate_and_upload.ts | 197 +------------- packages/monorepo-scripts/src/publish.ts | 3 +- .../monorepo-scripts/src/publish_release_notes.ts | 100 +------ .../monorepo-scripts/src/utils/publish_utils.ts | 291 +++++++++++++++++++++ 4 files changed, 294 insertions(+), 297 deletions(-) create mode 100644 packages/monorepo-scripts/src/utils/publish_utils.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index 03910c460..ab1f97ad8 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -1,13 +1,6 @@ -import { readFileSync, writeFileSync } from 'fs'; -import * as _ from 'lodash'; -import * as path from 'path'; -import { exec as execAsync } from 'promisify-child-process'; -import * as ts from 'typescript'; import * as yargs from 'yargs'; -import { constants } from './constants'; -import { ExportPathToExportedItems } from './types'; -import { utils } from './utils/utils'; +import { generateAndUploadDocsAsync } from './utils/publish_utils'; const args = yargs .option('package', { @@ -23,196 +16,8 @@ const args = yargs .example("$0 --package '0x.js' --isStaging true", 'Full usage example').argv; (async () => { - console.log('I RAN! - generateAndUploadDocsAsync'); const packageName = args.package; const isStaging = args.isStaging; - if (_.isEmpty(packageName)) { - return; // We are not runninng in a command-line env. - } await generateAndUploadDocsAsync(packageName, isStaging); })(); - -export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { - const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; - const indexPath = `${pathToPackage}/src/index.ts`; - const exportPathToExportedItems = getExportPathToExportedItems(indexPath); - - const monorepoPackages = utils.getPackages(constants.monorepoRootPath); - const pkg = _.find(monorepoPackages, monorepoPackage => { - return _.includes(monorepoPackage.packageJson.name, packageName); - }); - if (_.isUndefined(pkg)) { - throw new Error(`Couldn't find a package.json for ${packageName}`); - } - - const packageJson = pkg.packageJson; - const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); - if (!shouldPublishDocs) { - utils.log( - `GENERATE_UPLOAD_DOCS: ${ - packageJson.name - } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, - ); - return; - } - - const pkgNameToPath: { [name: string]: string } = {}; - _.each(monorepoPackages, pkg => { - pkgNameToPath[pkg.packageJson.name] = pkg.location; - }); - - // For each dep that is another one of our monorepo packages, we fetch it's index.ts - // and see which specific files we must pass to TypeDoc. - let typeDocExtraFileIncludes: string[] = []; - _.each(exportPathToExportedItems, (exportedItems, exportPath) => { - const pathIfExists = pkgNameToPath[exportPath]; - if (_.isUndefined(pathIfExists)) { - return; // It's an external package - } - - const isInternalToPkg = _.startsWith(exportPath, '.'); - if (isInternalToPkg) { - const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); - typeDocExtraFileIncludes.push(pathToInternalPkg); - } - const typeDocSourceIncludes = new Set(); - const pathToIndex = `${pathIfExists}/src/index.ts`; - const innerExportPathToExportedItems = getExportPathToExportedItems(pathToIndex); - _.each(exportedItems, exportName => { - _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { - if (!_.startsWith(innerExportPath, './')) { - throw new Error( - `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting on of ${exportedItems} which is - itself exported from an external package. To fix this, export the external dependency directly, - not indirectly through ${exportPath}.`, - ); - } - if (_.includes(innerExportItems, exportName)) { - const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); - typeDocSourceIncludes.add(absoluteSrcPath); - } - }); - }); - // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types - // directly, meaning no internal paths will exist to follow. Other packages also have direct exports - // in their index.ts, so we always add it to the source files passed to TypeDoc - typeDocSourceIncludes.add(pathToIndex); - - typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; - }); - - // Generate Typedoc JSON file - const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); - const projectFiles = typeDocExtraFileIncludes.join(' '); - const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); - // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the - // packages root dir, does not work. It only works when called via a `package.json` script located - // in the package's root. - await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { - cwd, - }); - - // For each entry, see if it was exported in index.ts. If not, remove it. - const typedocOutputString = readFileSync(jsonFilePath).toString(); - const typedocOutput = JSON.parse(typedocOutputString); - const finalTypeDocOutput = _.clone(typedocOutput); - _.each(typedocOutput.children, (file, i) => { - const exportItems = findExportItemsGivenTypedocName(exportPathToExportedItems, packageName, file.name); - _.each(file.children, (child, j) => { - if (!_.includes(exportItems, child.name)) { - delete finalTypeDocOutput.children[i].children[j]; - } - }); - finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); - }); - // Write modified TypeDoc JSON, without all the unexported stuff - writeFileSync(jsonFilePath, JSON.stringify(finalTypeDocOutput, null, 2)); - - const fileName = `v${packageJson.version}.json`; - utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); - const S3BucketPath = isStaging ? `s3://staging-doc-jsons/${packageName}/` : `s3://doc-jsons/${packageName}/`; - const s3Url = `${S3BucketPath}${fileName}`; - await execAsync( - `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, - { - cwd, - }, - ); - utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); - // Remove the generated docs directory - await execAsync(`rm -rf ${jsonFilePath}`, { - cwd, - }); -} - -function findExportItemsGivenTypedocName( - exportPathToExportedItems: ExportPathToExportedItems, - packageName: string, - typedocName: string, -): string[] { - const typeDocNameWithoutQuotes = _.replace(typedocName, '"', ''); - const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; - const exportPaths = _.keys(exportPathToExportedItems); - const sanitizedExportPaths = _.map(exportPaths, exportPath => { - if (_.startsWith(exportPath, './')) { - const sanitizedExportPath = path.join(packageName, 'src', exportPath); - sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; - return sanitizedExportPath; - } - const monorepoPrefix = '@0xproject/'; - if (_.startsWith(exportPath, monorepoPrefix)) { - const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; - sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; - return sanitizedExportPath; - } - sanitizedExportPathToExportPath[exportPath] = exportPath; - return exportPath; - }); - const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPaths, p => { - return _.startsWith(typeDocNameWithoutQuotes, p); - }); - if (_.isUndefined(matchingSanitizedExportPathIfExists)) { - throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); - } - const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; - return exportPathToExportedItems[matchingExportPath]; -} - -function getExportPathToExportedItems(pkgPath: string): ExportPathToExportedItems { - const sourceFile = ts.createSourceFile( - 'indexFile', - readFileSync(pkgPath).toString(), - ts.ScriptTarget.ES2017, - /*setParentNodes */ true, - ); - const exportPathToExportedItems = _getExportPathToExportedItems(sourceFile); - return exportPathToExportedItems; -} - -function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedItems { - const exportPathToExportedItems: ExportPathToExportedItems = {}; - processNode(sf); - - function processNode(node: ts.Node): void { - switch (node.kind) { - case ts.SyntaxKind.ExportDeclaration: - // console.log(node); - const exportClause = (node as any).exportClause; - const pkgName = exportClause.parent.moduleSpecifier.text; - _.each(exportClause.elements, element => { - exportPathToExportedItems[pkgName] = _.isUndefined(exportPathToExportedItems[pkgName]) - ? [element.name.escapedText] - : [...exportPathToExportedItems[pkgName], element.name.escapedText]; - }); - break; - - default: - // noop - break; - } - - ts.forEachChild(node, processNode); - } - return exportPathToExportedItems; -} diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index faaa268fc..64ba73e36 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -14,8 +14,7 @@ import { Package, PackageToNextVersion, VersionChangelog } from './types'; import { changelogUtils } from './utils/changelog_utils'; import { configs } from './utils/configs'; import { utils } from './utils/utils'; -import { generateAndUploadDocsAsync } from './doc_generate_and_upload'; -import { publishReleaseNotesAsync } from './publish_release_notes'; +import { publishReleaseNotesAsync, generateAndUploadDocsAsync } from './utils/publish_utils'; const DOC_GEN_COMMAND = 'docs:json'; const NPM_NAMESPACE = '@0xproject/'; diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index acfac0be7..d708e8275 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -1,110 +1,12 @@ -import { readFileSync } from 'fs'; -import * as _ from 'lodash'; import * as promisify from 'es6-promisify'; -import * as path from 'path'; -import { exec as execAsync } from 'promisify-child-process'; import * as publishRelease from 'publish-release'; -import { constants } from './constants'; -import { Package } from './types'; import { utils } from './utils/utils'; - -const publishReleaseAsync = promisify(publishRelease); +import { publishReleaseNotesAsync } from './utils/publish_utils'; (async () => { - console.log('I RAN! - publishReleaseNotesAsync'); const shouldIncludePrivate = false; const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); await publishReleaseNotesAsync(allUpdatedPackages); })(); - -export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { - // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) - const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); - const latestGitCommit = result.stdout; - const shortenedGitCommit = latestGitCommit.slice(0, 7); - const tagName = `monorepo@${shortenedGitCommit}`; - - await execAsync(`git rev-parse ${tagName}`); - await execAsync('git tag ${tagName}'); - - await execAsync('git push origin ${tagName}'); - const releaseName = `0x monorepo - ${shortenedGitCommit}`; - - let assets: string[] = []; - let aggregateNotes = ''; - _.each(updatedPublishPackages, pkg => { - const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); - if (_.isEmpty(notes)) { - return; // don't include it - } - aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; - - const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); - if (!_.isUndefined(packageAssets)) { - assets = [...assets, ...packageAssets]; - } - }); - const finalAssets = adjustAssetPaths(assets); - - utils.log('Publishing release notes ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 - await publishReleaseAsync({ - token: constants.githubPersonalAccessToken, - owner: '0xProject', - tag: tagName, - repo: '0x-monorepo', - name: releaseName, - notes: aggregateNotes, - draft: false, - prerelease: false, - reuseRelease: true, - reuseDraftOnly: false, - assets: finalAssets, - }); -} - -// Asset paths should described from the monorepo root. This method prefixes -// the supplied path with the absolute path to the monorepo root. -function adjustAssetPaths(assets: string[]): string[] { - const finalAssets: string[] = []; - _.each(assets, (asset: string) => { - const finalAsset = `${constants.monorepoRootPath}/${asset}`; - finalAssets.push(finalAsset); - }); - return finalAssets; -} - -function getReleaseNotesForPackage(packageName: string, version: string): string { - const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); - const changelogJSONPath = path.join( - constants.monorepoRootPath, - 'packages', - packageNameWithoutNamespace, - 'CHANGELOG.json', - ); - const changelogJSON = readFileSync(changelogJSONPath, 'utf-8'); - const changelogs = JSON.parse(changelogJSON); - const latestLog = changelogs[0]; - // If only has a `Dependencies updated` changelog, we don't include it in release notes - if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { - return ''; - } - // We sanity check that the version for the changelog notes we are about to publish to Github - // correspond to the new version of the package. - // if (version !== latestLog.version) { - // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); - // } - let notes = ''; - _.each(latestLog.changes, change => { - notes += `* ${change.note}`; - if (change.pr) { - notes += ` (#${change.pr})`; - } - notes += `\n`; - }); - return notes; -} diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts new file mode 100644 index 000000000..a0a414cda --- /dev/null +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -0,0 +1,291 @@ +import * as _ from 'lodash'; +import * as promisify from 'es6-promisify'; +import * as publishRelease from 'publish-release'; + +import { constants } from '../constants'; +import { Package } from '../types'; +import { utils } from './utils'; + +import { readFileSync, writeFileSync } from 'fs'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; +import * as ts from 'typescript'; + +import { ExportPathToExportedItems } from '../types'; + +const publishReleaseAsync = promisify(publishRelease); +export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { + // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) + const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); + const latestGitCommit = result.stdout; + const shortenedGitCommit = latestGitCommit.slice(0, 7); + const tagName = `monorepo@${shortenedGitCommit}`; + + await execAsync(`git rev-parse ${tagName}`); + await execAsync('git tag ${tagName}'); + + await execAsync('git push origin ${tagName}'); + const releaseName = `0x monorepo - ${shortenedGitCommit}`; + + let assets: string[] = []; + let aggregateNotes = ''; + _.each(updatedPublishPackages, pkg => { + const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); + if (_.isEmpty(notes)) { + return; // don't include it + } + aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; + + const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); + if (!_.isUndefined(packageAssets)) { + assets = [...assets, ...packageAssets]; + } + }); + const finalAssets = adjustAssetPaths(assets); + + utils.log('Publishing release notes ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync({ + token: constants.githubPersonalAccessToken, + owner: '0xProject', + tag: tagName, + repo: '0x-monorepo', + name: releaseName, + notes: aggregateNotes, + draft: false, + prerelease: false, + reuseRelease: true, + reuseDraftOnly: false, + assets: finalAssets, + }); +} + +// Asset paths should described from the monorepo root. This method prefixes +// the supplied path with the absolute path to the monorepo root. +function adjustAssetPaths(assets: string[]): string[] { + const finalAssets: string[] = []; + _.each(assets, (asset: string) => { + const finalAsset = `${constants.monorepoRootPath}/${asset}`; + finalAssets.push(finalAsset); + }); + return finalAssets; +} + +function getReleaseNotesForPackage(packageName: string, version: string): string { + const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); + const changelogJSONPath = path.join( + constants.monorepoRootPath, + 'packages', + packageNameWithoutNamespace, + 'CHANGELOG.json', + ); + const changelogJSON = readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + // If only has a `Dependencies updated` changelog, we don't include it in release notes + if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { + return ''; + } + // We sanity check that the version for the changelog notes we are about to publish to Github + // correspond to the new version of the package. + // if (version !== latestLog.version) { + // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); + // } + let notes = ''; + _.each(latestLog.changes, change => { + notes += `* ${change.note}`; + if (change.pr) { + notes += ` (#${change.pr})`; + } + notes += `\n`; + }); + return notes; +} + +export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { + const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; + const indexPath = `${pathToPackage}/src/index.ts`; + const exportPathToExportedItems = getExportPathToExportedItems(indexPath); + + const monorepoPackages = utils.getPackages(constants.monorepoRootPath); + const pkg = _.find(monorepoPackages, monorepoPackage => { + return _.includes(monorepoPackage.packageJson.name, packageName); + }); + if (_.isUndefined(pkg)) { + throw new Error(`Couldn't find a package.json for ${packageName}`); + } + + const packageJson = pkg.packageJson; + const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); + if (!shouldPublishDocs) { + utils.log( + `GENERATE_UPLOAD_DOCS: ${ + packageJson.name + } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, + ); + return; + } + + const pkgNameToPath: { [name: string]: string } = {}; + _.each(monorepoPackages, pkg => { + pkgNameToPath[pkg.packageJson.name] = pkg.location; + }); + + // For each dep that is another one of our monorepo packages, we fetch it's index.ts + // and see which specific files we must pass to TypeDoc. + let typeDocExtraFileIncludes: string[] = []; + _.each(exportPathToExportedItems, (exportedItems, exportPath) => { + const pathIfExists = pkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + return; // It's an external package + } + + const isInternalToPkg = _.startsWith(exportPath, '.'); + if (isInternalToPkg) { + const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); + typeDocExtraFileIncludes.push(pathToInternalPkg); + return; // Right? + } + const typeDocSourceIncludes = new Set(); + const pathToIndex = `${pathIfExists}/src/index.ts`; + const innerExportPathToExportedItems = getExportPathToExportedItems(pathToIndex); + _.each(exportedItems, exportName => { + _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { + if (!_.startsWith(innerExportPath, './') && _.includes(innerExportItems, exportName)) { + throw new Error( + `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is + itself exported from an external package. To fix this, export the external dependency directly, + not indirectly through ${innerExportPath}.`, + ); + } else if (_.includes(innerExportItems, exportName)) { + const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); + typeDocSourceIncludes.add(absoluteSrcPath); + } + }); + }); + // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types + // directly, meaning no internal paths will exist to follow. Other packages also have direct exports + // in their index.ts, so we always add it to the source files passed to TypeDoc + if (typeDocSourceIncludes.size === 0) { + typeDocSourceIncludes.add(pathToIndex); + } + + typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; + }); + + // Generate Typedoc JSON file + const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); + const projectFiles = typeDocExtraFileIncludes.join(' '); + const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); + // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the + // packages root dir, does not work. It only works when called via a `package.json` script located + // in the package's root. + await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { + cwd, + }); + + // For each entry, see if it was exported in index.ts. If not, remove it. + const typedocOutputString = readFileSync(jsonFilePath).toString(); + const typedocOutput = JSON.parse(typedocOutputString); + const finalTypeDocOutput = _.clone(typedocOutput); + _.each(typedocOutput.children, (file, i) => { + const exportItems = findExportItemsGivenTypedocName(exportPathToExportedItems, packageName, file.name); + _.each(file.children, (child, j) => { + if (!_.includes(exportItems, child.name)) { + delete finalTypeDocOutput.children[i].children[j]; + } + }); + finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); + }); + // Write modified TypeDoc JSON, without all the unexported stuff + writeFileSync(jsonFilePath, JSON.stringify(finalTypeDocOutput, null, 2)); + + const fileName = `v${packageJson.version}.json`; + utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); + const S3BucketPath = isStaging ? `s3://staging-doc-jsons/${packageName}/` : `s3://doc-jsons/${packageName}/`; + const s3Url = `${S3BucketPath}${fileName}`; + await execAsync( + `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, + { + cwd, + }, + ); + utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); + // Remove the generated docs directory + await execAsync(`rm -rf ${jsonFilePath}`, { + cwd, + }); +} + +function findExportItemsGivenTypedocName( + exportPathToExportedItems: ExportPathToExportedItems, + packageName: string, + typedocName: string, +): string[] { + const typeDocNameWithoutQuotes = _.replace(typedocName, '"', ''); + const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; + const exportPaths = _.keys(exportPathToExportedItems); + const sanitizedExportPaths = _.map(exportPaths, exportPath => { + if (_.startsWith(exportPath, './')) { + const sanitizedExportPath = path.join(packageName, 'src', exportPath); + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + const monorepoPrefix = '@0xproject/'; + if (_.startsWith(exportPath, monorepoPrefix)) { + const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + sanitizedExportPathToExportPath[exportPath] = exportPath; + return exportPath; + }); + const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPaths, p => { + return _.startsWith(typeDocNameWithoutQuotes, p); + }); + if (_.isUndefined(matchingSanitizedExportPathIfExists)) { + throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); + } + const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; + return exportPathToExportedItems[matchingExportPath]; +} + +function getExportPathToExportedItems(pkgPath: string): ExportPathToExportedItems { + const sourceFile = ts.createSourceFile( + 'indexFile', + readFileSync(pkgPath).toString(), + ts.ScriptTarget.ES2017, + /*setParentNodes */ true, + ); + const exportPathToExportedItems = _getExportPathToExportedItems(sourceFile); + return exportPathToExportedItems; +} + +function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedItems { + const exportPathToExportedItems: ExportPathToExportedItems = {}; + processNode(sf); + + function processNode(node: ts.Node): void { + switch (node.kind) { + case ts.SyntaxKind.ExportDeclaration: + // console.log(node); + const exportClause = (node as any).exportClause; + const pkgName = exportClause.parent.moduleSpecifier.text; + _.each(exportClause.elements, element => { + exportPathToExportedItems[pkgName] = _.isUndefined(exportPathToExportedItems[pkgName]) + ? [element.name.escapedText] + : [...exportPathToExportedItems[pkgName], element.name.escapedText]; + }); + break; + + default: + // noop + break; + } + + ts.forEachChild(node, processNode); + } + return exportPathToExportedItems; +} -- cgit v1.2.3 From 79b1b6c8e08f9cc61babd75fdaff14472216d0f2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 30 Jul 2018 15:40:10 +0200 Subject: Fix bugs in doc gen --- packages/monorepo-scripts/src/utils/publish_utils.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index a0a414cda..7209fa344 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -137,29 +137,33 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // and see which specific files we must pass to TypeDoc. let typeDocExtraFileIncludes: string[] = []; _.each(exportPathToExportedItems, (exportedItems, exportPath) => { - const pathIfExists = pkgNameToPath[exportPath]; - if (_.isUndefined(pathIfExists)) { - return; // It's an external package - } - const isInternalToPkg = _.startsWith(exportPath, '.'); if (isInternalToPkg) { const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); typeDocExtraFileIncludes.push(pathToInternalPkg); return; // Right? } + + const pathIfExists = pkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + return; // It's an external package + } + const typeDocSourceIncludes = new Set(); const pathToIndex = `${pathIfExists}/src/index.ts`; const innerExportPathToExportedItems = getExportPathToExportedItems(pathToIndex); _.each(exportedItems, exportName => { _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { - if (!_.startsWith(innerExportPath, './') && _.includes(innerExportItems, exportName)) { + if (!_.includes(innerExportItems, exportName)) { + return; + } + if (!_.startsWith(innerExportPath, './')) { throw new Error( `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is itself exported from an external package. To fix this, export the external dependency directly, not indirectly through ${innerExportPath}.`, ); - } else if (_.includes(innerExportItems, exportName)) { + } else { const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); typeDocSourceIncludes.add(absoluteSrcPath); } -- cgit v1.2.3 From b4f916d214dd80c11b4cb5db8af9545d5161f97d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 30 Jul 2018 21:09:17 +0200 Subject: Standardize child naming --- packages/monorepo-scripts/src/utils/publish_utils.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 7209fa344..9b5ff378e 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -190,10 +190,21 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: cwd, }); - // For each entry, see if it was exported in index.ts. If not, remove it. + // Unfortunately TypeDoc children names will only be prefixed with the name of the package _if_ we passed + // TypeDoc files outside of the packages root path (i.e this package exports another package found in our + // monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add + // it here when necessary. const typedocOutputString = readFileSync(jsonFilePath).toString(); const typedocOutput = JSON.parse(typedocOutputString); const finalTypeDocOutput = _.clone(typedocOutput); + _.each(typedocOutput.children, (child, i) => { + if (!_.includes(child.name, '/src/')) { + const nameWithoutQuotes = child.name.replace(/"/g, ''); + finalTypeDocOutput.children[i].name = `"${packageName}/src/${nameWithoutQuotes}"`; + } + }); + + // For each entry, see if it was exported in index.ts. If not, remove it. _.each(typedocOutput.children, (file, i) => { const exportItems = findExportItemsGivenTypedocName(exportPathToExportedItems, packageName, file.name); _.each(file.children, (child, j) => { -- cgit v1.2.3 From ba00cd916aee451255ece0e5cc354091cc309bc5 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 30 Jul 2018 21:09:56 +0200 Subject: Remove console --- packages/monorepo-scripts/src/utils/publish_utils.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 9b5ff378e..ff65c779c 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -285,7 +285,6 @@ function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedI function processNode(node: ts.Node): void { switch (node.kind) { case ts.SyntaxKind.ExportDeclaration: - // console.log(node); const exportClause = (node as any).exportClause; const pkgName = exportClause.parent.moduleSpecifier.text; _.each(exportClause.elements, element => { -- cgit v1.2.3 From 3bdf6004ca74dd9eb380aa61cf9e69c47725116a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 1 Aug 2018 17:36:37 +0200 Subject: Start refactoring docs to remove unnecessary configs given more concise TypeDoc JSON --- .../monorepo-scripts/src/utils/publish_utils.ts | 68 +++++++++++++++++----- 1 file changed, 54 insertions(+), 14 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index ff65c779c..01d44a369 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -13,6 +13,20 @@ import * as ts from 'typescript'; import { ExportPathToExportedItems } from '../types'; +interface ExportInfo { + exportPathToExportedItems: ExportPathToExportedItems; + exportPathOrder: string[]; +} + +interface ExportNameToTypedocName { + [exportName: string]: string; +} + +interface Metadata { + exportPathToTypedocName: ExportNameToTypedocName; + exportPathOrder: string[]; +} + const publishReleaseAsync = promisify(publishRelease); export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) @@ -107,7 +121,7 @@ function getReleaseNotesForPackage(packageName: string, version: string): string export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; const indexPath = `${pathToPackage}/src/index.ts`; - const exportPathToExportedItems = getExportPathToExportedItems(indexPath); + const { exportPathToExportedItems, exportPathOrder } = getExportPathToExportedItems(indexPath); const monorepoPackages = utils.getPackages(constants.monorepoRootPath); const pkg = _.find(monorepoPackages, monorepoPackage => { @@ -151,7 +165,8 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: const typeDocSourceIncludes = new Set(); const pathToIndex = `${pathIfExists}/src/index.ts`; - const innerExportPathToExportedItems = getExportPathToExportedItems(pathToIndex); + const exportInfo = getExportPathToExportedItems(pathToIndex); + const innerExportPathToExportedItems = exportInfo.exportPathToExportedItems; _.each(exportedItems, exportName => { _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { if (!_.includes(innerExportItems, exportName)) { @@ -200,13 +215,18 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: _.each(typedocOutput.children, (child, i) => { if (!_.includes(child.name, '/src/')) { const nameWithoutQuotes = child.name.replace(/"/g, ''); - finalTypeDocOutput.children[i].name = `"${packageName}/src/${nameWithoutQuotes}"`; + const standardizedName = `"${packageName}/src/${nameWithoutQuotes}"`; + finalTypeDocOutput.children[i].name = standardizedName; } }); // For each entry, see if it was exported in index.ts. If not, remove it. + const exportPathToTypedocName: ExportNameToTypedocName = {}; _.each(typedocOutput.children, (file, i) => { - const exportItems = findExportItemsGivenTypedocName(exportPathToExportedItems, packageName, file.name); + const exportPath = findExportPathGivenTypedocName(exportPathToExportedItems, packageName, file.name); + exportPathToTypedocName[exportPath] = file.name; + + const exportItems = exportPathToExportedItems[exportPath]; _.each(file.children, (child, j) => { if (!_.includes(exportItems, child.name)) { delete finalTypeDocOutput.children[i].children[j]; @@ -214,8 +234,22 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); }); + + // TODO: Add extra metadata for Class properties that are class instances + // Look in file for imports of that class, get the import name and construct a link to + // it's definition on another docs page. + + // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON + const docJson = { + metadata: { + exportPathToTypedocName, + exportPathOrder, + }, + typedocJson: finalTypeDocOutput, + }; + // Write modified TypeDoc JSON, without all the unexported stuff - writeFileSync(jsonFilePath, JSON.stringify(finalTypeDocOutput, null, 2)); + writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); const fileName = `v${packageJson.version}.json`; utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); @@ -234,11 +268,11 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); } -function findExportItemsGivenTypedocName( +function findExportPathGivenTypedocName( exportPathToExportedItems: ExportPathToExportedItems, packageName: string, typedocName: string, -): string[] { +): string { const typeDocNameWithoutQuotes = _.replace(typedocName, '"', ''); const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; const exportPaths = _.keys(exportPathToExportedItems); @@ -264,22 +298,23 @@ function findExportItemsGivenTypedocName( throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); } const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; - return exportPathToExportedItems[matchingExportPath]; + return matchingExportPath; } -function getExportPathToExportedItems(pkgPath: string): ExportPathToExportedItems { +function getExportPathToExportedItems(filePath: string): ExportInfo { const sourceFile = ts.createSourceFile( 'indexFile', - readFileSync(pkgPath).toString(), + readFileSync(filePath).toString(), ts.ScriptTarget.ES2017, /*setParentNodes */ true, ); - const exportPathToExportedItems = _getExportPathToExportedItems(sourceFile); - return exportPathToExportedItems; + const exportInfo = _getExportPathToExportedItems(sourceFile); + return exportInfo; } -function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedItems { +function _getExportPathToExportedItems(sf: ts.SourceFile): ExportInfo { const exportPathToExportedItems: ExportPathToExportedItems = {}; + const exportPathOrder: string[] = []; processNode(sf); function processNode(node: ts.Node): void { @@ -287,6 +322,7 @@ function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedI case ts.SyntaxKind.ExportDeclaration: const exportClause = (node as any).exportClause; const pkgName = exportClause.parent.moduleSpecifier.text; + exportPathOrder.push(pkgName); _.each(exportClause.elements, element => { exportPathToExportedItems[pkgName] = _.isUndefined(exportPathToExportedItems[pkgName]) ? [element.name.escapedText] @@ -301,5 +337,9 @@ function _getExportPathToExportedItems(sf: ts.SourceFile): ExportPathToExportedI ts.forEachChild(node, processNode); } - return exportPathToExportedItems; + const exportInfo = { + exportPathToExportedItems, + exportPathOrder, + }; + return exportInfo; } -- cgit v1.2.3 From 71a2f2d72172e4138b3d4d40ab6bbee4b90e4cf7 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 2 Aug 2018 17:25:18 +0200 Subject: We need to always include the globals.d.ts otherwise TS complains about .json imports --- packages/monorepo-scripts/src/utils/publish_utils.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 01d44a369..3cdd2c4fb 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -195,6 +195,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); // Generate Typedoc JSON file + typeDocExtraFileIncludes.push(path.join(pathToPackage, 'src', 'globals.d.ts')); const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); const projectFiles = typeDocExtraFileIncludes.join(' '); const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); -- cgit v1.2.3 From 987971bd59c282e885679576262732e9afa297bb Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 2 Aug 2018 17:26:53 +0200 Subject: Fix bug where if there were multiple matches, it wouldn't always take the longest match --- packages/monorepo-scripts/src/utils/publish_utils.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 3cdd2c4fb..974fb4d0d 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -274,7 +274,7 @@ function findExportPathGivenTypedocName( packageName: string, typedocName: string, ): string { - const typeDocNameWithoutQuotes = _.replace(typedocName, '"', ''); + const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; const exportPaths = _.keys(exportPathToExportedItems); const sanitizedExportPaths = _.map(exportPaths, exportPath => { @@ -292,7 +292,13 @@ function findExportPathGivenTypedocName( sanitizedExportPathToExportPath[exportPath] = exportPath; return exportPath; }); - const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPaths, p => { + // We need to sort the exportPaths by length (longest first), so that the match finding will pick + // longer matches before shorter matches, since it might match both, but the longer match is more + // precisely what we are looking for. + const sanitizedExportPathsSortedByLength = sanitizedExportPaths.sort((a: string, b: string) => { + return b.length - a.length; + }); + const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPathsSortedByLength, p => { return _.startsWith(typeDocNameWithoutQuotes, p); }); if (_.isUndefined(matchingSanitizedExportPathIfExists)) { -- cgit v1.2.3 From faa980ffc3bde48e4aaca665c8be83ea4c44b106 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 2 Aug 2018 21:08:21 +0200 Subject: Add ability to omit rendering specific exports and also support direct exports from index.ts --- .../monorepo-scripts/src/utils/publish_utils.ts | 52 ++++++++++++++++------ 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 974fb4d0d..2cf67946b 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -119,10 +119,6 @@ function getReleaseNotesForPackage(packageName: string, version: string): string } export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { - const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; - const indexPath = `${pathToPackage}/src/index.ts`; - const { exportPathToExportedItems, exportPathOrder } = getExportPathToExportedItems(indexPath); - const monorepoPackages = utils.getPackages(constants.monorepoRootPath); const pkg = _.find(monorepoPackages, monorepoPackage => { return _.includes(monorepoPackage.packageJson.name, packageName); @@ -132,6 +128,12 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: } const packageJson = pkg.packageJson; + const omitExports = _.get(packageJson, 'config.postpublish.omitExports', []); + + const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; + const indexPath = `${pathToPackage}/src/index.ts`; + const { exportPathToExportedItems, exportPathOrder } = getExportPathToExportedItems(indexPath, omitExports); + const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); if (!shouldPublishDocs) { utils.log( @@ -308,35 +310,59 @@ function findExportPathGivenTypedocName( return matchingExportPath; } -function getExportPathToExportedItems(filePath: string): ExportInfo { +function getExportPathToExportedItems(filePath: string, omitExports?: string[]): ExportInfo { const sourceFile = ts.createSourceFile( 'indexFile', readFileSync(filePath).toString(), ts.ScriptTarget.ES2017, /*setParentNodes */ true, ); - const exportInfo = _getExportPathToExportedItems(sourceFile); + const exportInfo = _getExportPathToExportedItems(sourceFile, omitExports); return exportInfo; } -function _getExportPathToExportedItems(sf: ts.SourceFile): ExportInfo { +function _getExportPathToExportedItems(sf: ts.SourceFile, omitExports?: string[]): ExportInfo { const exportPathToExportedItems: ExportPathToExportedItems = {}; const exportPathOrder: string[] = []; + const exportsToOmit = _.isUndefined(omitExports) ? [] : omitExports; + console.log('exportsToOmit', exportsToOmit); processNode(sf); function processNode(node: ts.Node): void { switch (node.kind) { - case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportDeclaration: { const exportClause = (node as any).exportClause; - const pkgName = exportClause.parent.moduleSpecifier.text; - exportPathOrder.push(pkgName); + const exportPath = exportClause.parent.moduleSpecifier.text; _.each(exportClause.elements, element => { - exportPathToExportedItems[pkgName] = _.isUndefined(exportPathToExportedItems[pkgName]) - ? [element.name.escapedText] - : [...exportPathToExportedItems[pkgName], element.name.escapedText]; + const exportItem = element.name.escapedText; + if (!_.includes(exportsToOmit, exportItem)) { + exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) + ? [exportItem] + : [...exportPathToExportedItems[exportPath], exportItem]; + } }); + if (!_.isUndefined(exportPathToExportedItems[exportPath])) { + exportPathOrder.push(exportPath); + } break; + } + case ts.SyntaxKind.ExportKeyword: { + const foundNode: any = node; + const exportPath = './index'; + if (foundNode.parent && foundNode.parent.name) { + const exportItem = foundNode.parent.name.escapedText; + if (!_.includes(exportsToOmit, exportItem)) { + exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) + ? [exportItem] + : [...exportPathToExportedItems[exportPath], exportItem]; + } + } + if (!_.includes(exportPathOrder, exportPath) && !_.isUndefined(exportPathToExportedItems[exportPath])) { + exportPathOrder.push(exportPath); + } + break; + } default: // noop break; -- cgit v1.2.3 From fdcb42d8e17f4f5f324dd644077a07cbd4be65c7 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 6 Aug 2018 15:27:28 -0400 Subject: Fix bug where we only rendered one TypeDoc JSON key per export, instead of all of them --- packages/monorepo-scripts/src/utils/publish_utils.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 2cf67946b..709a48799 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -18,12 +18,12 @@ interface ExportInfo { exportPathOrder: string[]; } -interface ExportNameToTypedocName { - [exportName: string]: string; +interface ExportNameToTypedocNames { + [exportName: string]: string[]; } interface Metadata { - exportPathToTypedocName: ExportNameToTypedocName; + exportPathToTypedocNames: ExportNameToTypedocNames; exportPathOrder: string[]; } @@ -224,10 +224,12 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); // For each entry, see if it was exported in index.ts. If not, remove it. - const exportPathToTypedocName: ExportNameToTypedocName = {}; + const exportPathToTypedocNames: ExportNameToTypedocNames = {}; _.each(typedocOutput.children, (file, i) => { const exportPath = findExportPathGivenTypedocName(exportPathToExportedItems, packageName, file.name); - exportPathToTypedocName[exportPath] = file.name; + exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) + ? [file.name] + : [...exportPathToTypedocNames[exportPath], file.name]; const exportItems = exportPathToExportedItems[exportPath]; _.each(file.children, (child, j) => { @@ -245,7 +247,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON const docJson = { metadata: { - exportPathToTypedocName, + exportPathToTypedocNames, exportPathOrder, }, typedocJson: finalTypeDocOutput, -- cgit v1.2.3 From bc5835229df6e68473279a1ac646ca50bf4092a3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 6 Aug 2018 15:31:52 -0400 Subject: Remove stray console log --- packages/monorepo-scripts/src/utils/publish_utils.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts index 709a48799..13edb70d2 100644 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ b/packages/monorepo-scripts/src/utils/publish_utils.ts @@ -327,7 +327,6 @@ function _getExportPathToExportedItems(sf: ts.SourceFile, omitExports?: string[] const exportPathToExportedItems: ExportPathToExportedItems = {}; const exportPathOrder: string[] = []; const exportsToOmit = _.isUndefined(omitExports) ? [] : omitExports; - console.log('exportsToOmit', exportsToOmit); processNode(sf); function processNode(node: ts.Node): void { -- cgit v1.2.3 From 9f42ceb5a3962c3e9e251da8791182e561139b08 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 8 Aug 2018 09:47:06 -0400 Subject: Split publish_utils since it was becoming too big and unwieldy --- .../src/doc_generate_and_upload.ts | 2 +- packages/monorepo-scripts/src/publish.ts | 3 +- .../monorepo-scripts/src/publish_release_notes.ts | 2 +- .../src/utils/doc_generate_and_upload_utils.ts | 280 +++++++++++++++ .../src/utils/github_release_utils.ts | 102 ++++++ .../monorepo-scripts/src/utils/publish_utils.ts | 379 --------------------- 6 files changed, 386 insertions(+), 382 deletions(-) create mode 100644 packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts create mode 100644 packages/monorepo-scripts/src/utils/github_release_utils.ts delete mode 100644 packages/monorepo-scripts/src/utils/publish_utils.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index ab1f97ad8..e0e7e1bb5 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -1,6 +1,6 @@ import * as yargs from 'yargs'; -import { generateAndUploadDocsAsync } from './utils/publish_utils'; +import { generateAndUploadDocsAsync } from './utils/doc_generate_and_upload_utils'; const args = yargs .option('package', { diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 64ba73e36..932d912b8 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -14,7 +14,8 @@ import { Package, PackageToNextVersion, VersionChangelog } from './types'; import { changelogUtils } from './utils/changelog_utils'; import { configs } from './utils/configs'; import { utils } from './utils/utils'; -import { publishReleaseNotesAsync, generateAndUploadDocsAsync } from './utils/publish_utils'; +import { publishReleaseNotesAsync } from './utils/github_release_utils'; +import { generateAndUploadDocsAsync } from './utils/doc_generate_and_upload_utils'; const DOC_GEN_COMMAND = 'docs:json'; const NPM_NAMESPACE = '@0xproject/'; diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index d708e8275..964f5b0bb 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -2,7 +2,7 @@ import * as promisify from 'es6-promisify'; import * as publishRelease from 'publish-release'; import { utils } from './utils/utils'; -import { publishReleaseNotesAsync } from './utils/publish_utils'; +import { publishReleaseNotesAsync } from './utils/github_release_utils'; (async () => { const shouldIncludePrivate = false; diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts new file mode 100644 index 000000000..870cbe17c --- /dev/null +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -0,0 +1,280 @@ +import * as _ from 'lodash'; + +import { constants } from '../constants'; +import { utils } from './utils'; + +import { readFileSync, writeFileSync } from 'fs'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; +import * as ts from 'typescript'; + +import { ExportPathToExportedItems } from '../types'; + +interface ExportInfo { + exportPathToExportedItems: ExportPathToExportedItems; + exportPathOrder: string[]; +} + +interface ExportNameToTypedocNames { + [exportName: string]: string[]; +} + +export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { + const monorepoPackages = utils.getPackages(constants.monorepoRootPath); + const pkg = _.find(monorepoPackages, monorepoPackage => { + return _.includes(monorepoPackage.packageJson.name, packageName); + }); + if (_.isUndefined(pkg)) { + throw new Error(`Couldn't find a package.json for ${packageName}`); + } + + const packageJson = pkg.packageJson; + const omitExports = _.get(packageJson, 'config.postpublish.omitExports', []); + + const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; + const indexPath = `${pathToPackage}/src/index.ts`; + const { exportPathToExportedItems, exportPathOrder } = getExportPathToExportedItems(indexPath, omitExports); + + const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); + if (!shouldPublishDocs) { + utils.log( + `GENERATE_UPLOAD_DOCS: ${ + packageJson.name + } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, + ); + return; + } + + const pkgNameToPath: { [name: string]: string } = {}; + _.each(monorepoPackages, pkg => { + pkgNameToPath[pkg.packageJson.name] = pkg.location; + }); + + // For each dep that is another one of our monorepo packages, we fetch it's index.ts + // and see which specific files we must pass to TypeDoc. + let typeDocExtraFileIncludes: string[] = []; + _.each(exportPathToExportedItems, (exportedItems, exportPath) => { + const isInternalToPkg = _.startsWith(exportPath, '.'); + if (isInternalToPkg) { + const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); + typeDocExtraFileIncludes.push(pathToInternalPkg); + return; // Right? + } + + const pathIfExists = pkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + return; // It's an external package + } + + const typeDocSourceIncludes = new Set(); + const pathToIndex = `${pathIfExists}/src/index.ts`; + const exportInfo = getExportPathToExportedItems(pathToIndex); + const innerExportPathToExportedItems = exportInfo.exportPathToExportedItems; + _.each(exportedItems, exportName => { + _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { + if (!_.includes(innerExportItems, exportName)) { + return; + } + if (!_.startsWith(innerExportPath, './')) { + throw new Error( + `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is + itself exported from an external package. To fix this, export the external dependency directly, + not indirectly through ${innerExportPath}.`, + ); + } else { + const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); + typeDocSourceIncludes.add(absoluteSrcPath); + } + }); + }); + // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types + // directly, meaning no internal paths will exist to follow. Other packages also have direct exports + // in their index.ts, so we always add it to the source files passed to TypeDoc + if (typeDocSourceIncludes.size === 0) { + typeDocSourceIncludes.add(pathToIndex); + } + + typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; + }); + + // Generate Typedoc JSON file + typeDocExtraFileIncludes.push(path.join(pathToPackage, 'src', 'globals.d.ts')); + const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); + const projectFiles = typeDocExtraFileIncludes.join(' '); + const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); + // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the + // packages root dir, does not work. It only works when called via a `package.json` script located + // in the package's root. + await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { + cwd, + }); + + // Unfortunately TypeDoc children names will only be prefixed with the name of the package _if_ we passed + // TypeDoc files outside of the packages root path (i.e this package exports another package found in our + // monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add + // it here when necessary. + const typedocOutputString = readFileSync(jsonFilePath).toString(); + const typedocOutput = JSON.parse(typedocOutputString); + const finalTypeDocOutput = _.clone(typedocOutput); + _.each(typedocOutput.children, (child, i) => { + if (!_.includes(child.name, '/src/')) { + const nameWithoutQuotes = child.name.replace(/"/g, ''); + const standardizedName = `"${packageName}/src/${nameWithoutQuotes}"`; + finalTypeDocOutput.children[i].name = standardizedName; + } + }); + + // For each entry, see if it was exported in index.ts. If not, remove it. + const exportPathToTypedocNames: ExportNameToTypedocNames = {}; + _.each(typedocOutput.children, (file, i) => { + const exportPath = findExportPathGivenTypedocName(exportPathToExportedItems, packageName, file.name); + exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) + ? [file.name] + : [...exportPathToTypedocNames[exportPath], file.name]; + + const exportItems = exportPathToExportedItems[exportPath]; + _.each(file.children, (child, j) => { + if (!_.includes(exportItems, child.name)) { + delete finalTypeDocOutput.children[i].children[j]; + } + }); + finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); + }); + + // TODO: Add extra metadata for Class properties that are class instances + // Look in file for imports of that class, get the import name and construct a link to + // it's definition on another docs page. + + // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON + const docJson = { + metadata: { + exportPathToTypedocNames, + exportPathOrder, + }, + typedocJson: finalTypeDocOutput, + }; + + // Write modified TypeDoc JSON, without all the unexported stuff + writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); + + const fileName = `v${packageJson.version}.json`; + utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); + const S3BucketPath = isStaging ? `s3://staging-doc-jsons/${packageName}/` : `s3://doc-jsons/${packageName}/`; + const s3Url = `${S3BucketPath}${fileName}`; + await execAsync( + `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, + { + cwd, + }, + ); + utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); + // Remove the generated docs directory + await execAsync(`rm -rf ${jsonFilePath}`, { + cwd, + }); +} + +function findExportPathGivenTypedocName( + exportPathToExportedItems: ExportPathToExportedItems, + packageName: string, + typedocName: string, +): string { + const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); + const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; + const exportPaths = _.keys(exportPathToExportedItems); + const sanitizedExportPaths = _.map(exportPaths, exportPath => { + if (_.startsWith(exportPath, './')) { + const sanitizedExportPath = path.join(packageName, 'src', exportPath); + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + const monorepoPrefix = '@0xproject/'; + if (_.startsWith(exportPath, monorepoPrefix)) { + const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + sanitizedExportPathToExportPath[exportPath] = exportPath; + return exportPath; + }); + // We need to sort the exportPaths by length (longest first), so that the match finding will pick + // longer matches before shorter matches, since it might match both, but the longer match is more + // precisely what we are looking for. + const sanitizedExportPathsSortedByLength = sanitizedExportPaths.sort((a: string, b: string) => { + return b.length - a.length; + }); + const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPathsSortedByLength, p => { + return _.startsWith(typeDocNameWithoutQuotes, p); + }); + if (_.isUndefined(matchingSanitizedExportPathIfExists)) { + throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); + } + const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; + return matchingExportPath; +} + +function getExportPathToExportedItems(filePath: string, omitExports?: string[]): ExportInfo { + const sourceFile = ts.createSourceFile( + 'indexFile', + readFileSync(filePath).toString(), + ts.ScriptTarget.ES2017, + /*setParentNodes */ true, + ); + const exportInfo = _getExportPathToExportedItems(sourceFile, omitExports); + return exportInfo; +} + +function _getExportPathToExportedItems(sf: ts.SourceFile, omitExports?: string[]): ExportInfo { + const exportPathToExportedItems: ExportPathToExportedItems = {}; + const exportPathOrder: string[] = []; + const exportsToOmit = _.isUndefined(omitExports) ? [] : omitExports; + processNode(sf); + + function processNode(node: ts.Node): void { + switch (node.kind) { + case ts.SyntaxKind.ExportDeclaration: { + const exportClause = (node as any).exportClause; + const exportPath = exportClause.parent.moduleSpecifier.text; + _.each(exportClause.elements, element => { + const exportItem = element.name.escapedText; + if (!_.includes(exportsToOmit, exportItem)) { + exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) + ? [exportItem] + : [...exportPathToExportedItems[exportPath], exportItem]; + } + }); + if (!_.isUndefined(exportPathToExportedItems[exportPath])) { + exportPathOrder.push(exportPath); + } + break; + } + + case ts.SyntaxKind.ExportKeyword: { + const foundNode: any = node; + const exportPath = './index'; + if (foundNode.parent && foundNode.parent.name) { + const exportItem = foundNode.parent.name.escapedText; + if (!_.includes(exportsToOmit, exportItem)) { + exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) + ? [exportItem] + : [...exportPathToExportedItems[exportPath], exportItem]; + } + } + if (!_.includes(exportPathOrder, exportPath) && !_.isUndefined(exportPathToExportedItems[exportPath])) { + exportPathOrder.push(exportPath); + } + break; + } + default: + // noop + break; + } + + ts.forEachChild(node, processNode); + } + const exportInfo = { + exportPathToExportedItems, + exportPathOrder, + }; + return exportInfo; +} diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts new file mode 100644 index 000000000..1f4c4f1e9 --- /dev/null +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -0,0 +1,102 @@ +import * as _ from 'lodash'; +import * as promisify from 'es6-promisify'; +import * as publishRelease from 'publish-release'; + +import { constants } from '../constants'; +import { Package } from '../types'; +import { utils } from './utils'; + +import { readFileSync } from 'fs'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; + +const publishReleaseAsync = promisify(publishRelease); +export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { + // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) + const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); + const latestGitCommit = result.stdout; + const shortenedGitCommit = latestGitCommit.slice(0, 7); + const tagName = `monorepo@${shortenedGitCommit}`; + + await execAsync(`git rev-parse ${tagName}`); + await execAsync('git tag ${tagName}'); + + await execAsync('git push origin ${tagName}'); + const releaseName = `0x monorepo - ${shortenedGitCommit}`; + + let assets: string[] = []; + let aggregateNotes = ''; + _.each(updatedPublishPackages, pkg => { + const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); + if (_.isEmpty(notes)) { + return; // don't include it + } + aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; + + const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); + if (!_.isUndefined(packageAssets)) { + assets = [...assets, ...packageAssets]; + } + }); + const finalAssets = adjustAssetPaths(assets); + + utils.log('Publishing release notes ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync({ + token: constants.githubPersonalAccessToken, + owner: '0xProject', + tag: tagName, + repo: '0x-monorepo', + name: releaseName, + notes: aggregateNotes, + draft: false, + prerelease: false, + reuseRelease: true, + reuseDraftOnly: false, + assets: finalAssets, + }); +} + +// Asset paths should described from the monorepo root. This method prefixes +// the supplied path with the absolute path to the monorepo root. +function adjustAssetPaths(assets: string[]): string[] { + const finalAssets: string[] = []; + _.each(assets, (asset: string) => { + const finalAsset = `${constants.monorepoRootPath}/${asset}`; + finalAssets.push(finalAsset); + }); + return finalAssets; +} + +function getReleaseNotesForPackage(packageName: string, version: string): string { + const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); + const changelogJSONPath = path.join( + constants.monorepoRootPath, + 'packages', + packageNameWithoutNamespace, + 'CHANGELOG.json', + ); + const changelogJSON = readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + // If only has a `Dependencies updated` changelog, we don't include it in release notes + if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { + return ''; + } + // We sanity check that the version for the changelog notes we are about to publish to Github + // correspond to the new version of the package. + // if (version !== latestLog.version) { + // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); + // } + let notes = ''; + _.each(latestLog.changes, change => { + notes += `* ${change.note}`; + if (change.pr) { + notes += ` (#${change.pr})`; + } + notes += `\n`; + }); + return notes; +} diff --git a/packages/monorepo-scripts/src/utils/publish_utils.ts b/packages/monorepo-scripts/src/utils/publish_utils.ts deleted file mode 100644 index 13edb70d2..000000000 --- a/packages/monorepo-scripts/src/utils/publish_utils.ts +++ /dev/null @@ -1,379 +0,0 @@ -import * as _ from 'lodash'; -import * as promisify from 'es6-promisify'; -import * as publishRelease from 'publish-release'; - -import { constants } from '../constants'; -import { Package } from '../types'; -import { utils } from './utils'; - -import { readFileSync, writeFileSync } from 'fs'; -import * as path from 'path'; -import { exec as execAsync } from 'promisify-child-process'; -import * as ts from 'typescript'; - -import { ExportPathToExportedItems } from '../types'; - -interface ExportInfo { - exportPathToExportedItems: ExportPathToExportedItems; - exportPathOrder: string[]; -} - -interface ExportNameToTypedocNames { - [exportName: string]: string[]; -} - -interface Metadata { - exportPathToTypedocNames: ExportNameToTypedocNames; - exportPathOrder: string[]; -} - -const publishReleaseAsync = promisify(publishRelease); -export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { - // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) - const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); - const latestGitCommit = result.stdout; - const shortenedGitCommit = latestGitCommit.slice(0, 7); - const tagName = `monorepo@${shortenedGitCommit}`; - - await execAsync(`git rev-parse ${tagName}`); - await execAsync('git tag ${tagName}'); - - await execAsync('git push origin ${tagName}'); - const releaseName = `0x monorepo - ${shortenedGitCommit}`; - - let assets: string[] = []; - let aggregateNotes = ''; - _.each(updatedPublishPackages, pkg => { - const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); - if (_.isEmpty(notes)) { - return; // don't include it - } - aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; - - const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); - if (!_.isUndefined(packageAssets)) { - assets = [...assets, ...packageAssets]; - } - }); - const finalAssets = adjustAssetPaths(assets); - - utils.log('Publishing release notes ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 - await publishReleaseAsync({ - token: constants.githubPersonalAccessToken, - owner: '0xProject', - tag: tagName, - repo: '0x-monorepo', - name: releaseName, - notes: aggregateNotes, - draft: false, - prerelease: false, - reuseRelease: true, - reuseDraftOnly: false, - assets: finalAssets, - }); -} - -// Asset paths should described from the monorepo root. This method prefixes -// the supplied path with the absolute path to the monorepo root. -function adjustAssetPaths(assets: string[]): string[] { - const finalAssets: string[] = []; - _.each(assets, (asset: string) => { - const finalAsset = `${constants.monorepoRootPath}/${asset}`; - finalAssets.push(finalAsset); - }); - return finalAssets; -} - -function getReleaseNotesForPackage(packageName: string, version: string): string { - const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); - const changelogJSONPath = path.join( - constants.monorepoRootPath, - 'packages', - packageNameWithoutNamespace, - 'CHANGELOG.json', - ); - const changelogJSON = readFileSync(changelogJSONPath, 'utf-8'); - const changelogs = JSON.parse(changelogJSON); - const latestLog = changelogs[0]; - // If only has a `Dependencies updated` changelog, we don't include it in release notes - if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { - return ''; - } - // We sanity check that the version for the changelog notes we are about to publish to Github - // correspond to the new version of the package. - // if (version !== latestLog.version) { - // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); - // } - let notes = ''; - _.each(latestLog.changes, change => { - notes += `* ${change.note}`; - if (change.pr) { - notes += ` (#${change.pr})`; - } - notes += `\n`; - }); - return notes; -} - -export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { - const monorepoPackages = utils.getPackages(constants.monorepoRootPath); - const pkg = _.find(monorepoPackages, monorepoPackage => { - return _.includes(monorepoPackage.packageJson.name, packageName); - }); - if (_.isUndefined(pkg)) { - throw new Error(`Couldn't find a package.json for ${packageName}`); - } - - const packageJson = pkg.packageJson; - const omitExports = _.get(packageJson, 'config.postpublish.omitExports', []); - - const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; - const indexPath = `${pathToPackage}/src/index.ts`; - const { exportPathToExportedItems, exportPathOrder } = getExportPathToExportedItems(indexPath, omitExports); - - const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); - if (!shouldPublishDocs) { - utils.log( - `GENERATE_UPLOAD_DOCS: ${ - packageJson.name - } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, - ); - return; - } - - const pkgNameToPath: { [name: string]: string } = {}; - _.each(monorepoPackages, pkg => { - pkgNameToPath[pkg.packageJson.name] = pkg.location; - }); - - // For each dep that is another one of our monorepo packages, we fetch it's index.ts - // and see which specific files we must pass to TypeDoc. - let typeDocExtraFileIncludes: string[] = []; - _.each(exportPathToExportedItems, (exportedItems, exportPath) => { - const isInternalToPkg = _.startsWith(exportPath, '.'); - if (isInternalToPkg) { - const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); - typeDocExtraFileIncludes.push(pathToInternalPkg); - return; // Right? - } - - const pathIfExists = pkgNameToPath[exportPath]; - if (_.isUndefined(pathIfExists)) { - return; // It's an external package - } - - const typeDocSourceIncludes = new Set(); - const pathToIndex = `${pathIfExists}/src/index.ts`; - const exportInfo = getExportPathToExportedItems(pathToIndex); - const innerExportPathToExportedItems = exportInfo.exportPathToExportedItems; - _.each(exportedItems, exportName => { - _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { - if (!_.includes(innerExportItems, exportName)) { - return; - } - if (!_.startsWith(innerExportPath, './')) { - throw new Error( - `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is - itself exported from an external package. To fix this, export the external dependency directly, - not indirectly through ${innerExportPath}.`, - ); - } else { - const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); - typeDocSourceIncludes.add(absoluteSrcPath); - } - }); - }); - // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types - // directly, meaning no internal paths will exist to follow. Other packages also have direct exports - // in their index.ts, so we always add it to the source files passed to TypeDoc - if (typeDocSourceIncludes.size === 0) { - typeDocSourceIncludes.add(pathToIndex); - } - - typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; - }); - - // Generate Typedoc JSON file - typeDocExtraFileIncludes.push(path.join(pathToPackage, 'src', 'globals.d.ts')); - const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); - const projectFiles = typeDocExtraFileIncludes.join(' '); - const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); - // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the - // packages root dir, does not work. It only works when called via a `package.json` script located - // in the package's root. - await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { - cwd, - }); - - // Unfortunately TypeDoc children names will only be prefixed with the name of the package _if_ we passed - // TypeDoc files outside of the packages root path (i.e this package exports another package found in our - // monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add - // it here when necessary. - const typedocOutputString = readFileSync(jsonFilePath).toString(); - const typedocOutput = JSON.parse(typedocOutputString); - const finalTypeDocOutput = _.clone(typedocOutput); - _.each(typedocOutput.children, (child, i) => { - if (!_.includes(child.name, '/src/')) { - const nameWithoutQuotes = child.name.replace(/"/g, ''); - const standardizedName = `"${packageName}/src/${nameWithoutQuotes}"`; - finalTypeDocOutput.children[i].name = standardizedName; - } - }); - - // For each entry, see if it was exported in index.ts. If not, remove it. - const exportPathToTypedocNames: ExportNameToTypedocNames = {}; - _.each(typedocOutput.children, (file, i) => { - const exportPath = findExportPathGivenTypedocName(exportPathToExportedItems, packageName, file.name); - exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) - ? [file.name] - : [...exportPathToTypedocNames[exportPath], file.name]; - - const exportItems = exportPathToExportedItems[exportPath]; - _.each(file.children, (child, j) => { - if (!_.includes(exportItems, child.name)) { - delete finalTypeDocOutput.children[i].children[j]; - } - }); - finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); - }); - - // TODO: Add extra metadata for Class properties that are class instances - // Look in file for imports of that class, get the import name and construct a link to - // it's definition on another docs page. - - // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON - const docJson = { - metadata: { - exportPathToTypedocNames, - exportPathOrder, - }, - typedocJson: finalTypeDocOutput, - }; - - // Write modified TypeDoc JSON, without all the unexported stuff - writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); - - const fileName = `v${packageJson.version}.json`; - utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); - const S3BucketPath = isStaging ? `s3://staging-doc-jsons/${packageName}/` : `s3://doc-jsons/${packageName}/`; - const s3Url = `${S3BucketPath}${fileName}`; - await execAsync( - `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, - { - cwd, - }, - ); - utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); - // Remove the generated docs directory - await execAsync(`rm -rf ${jsonFilePath}`, { - cwd, - }); -} - -function findExportPathGivenTypedocName( - exportPathToExportedItems: ExportPathToExportedItems, - packageName: string, - typedocName: string, -): string { - const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); - const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; - const exportPaths = _.keys(exportPathToExportedItems); - const sanitizedExportPaths = _.map(exportPaths, exportPath => { - if (_.startsWith(exportPath, './')) { - const sanitizedExportPath = path.join(packageName, 'src', exportPath); - sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; - return sanitizedExportPath; - } - const monorepoPrefix = '@0xproject/'; - if (_.startsWith(exportPath, monorepoPrefix)) { - const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; - sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; - return sanitizedExportPath; - } - sanitizedExportPathToExportPath[exportPath] = exportPath; - return exportPath; - }); - // We need to sort the exportPaths by length (longest first), so that the match finding will pick - // longer matches before shorter matches, since it might match both, but the longer match is more - // precisely what we are looking for. - const sanitizedExportPathsSortedByLength = sanitizedExportPaths.sort((a: string, b: string) => { - return b.length - a.length; - }); - const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPathsSortedByLength, p => { - return _.startsWith(typeDocNameWithoutQuotes, p); - }); - if (_.isUndefined(matchingSanitizedExportPathIfExists)) { - throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); - } - const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; - return matchingExportPath; -} - -function getExportPathToExportedItems(filePath: string, omitExports?: string[]): ExportInfo { - const sourceFile = ts.createSourceFile( - 'indexFile', - readFileSync(filePath).toString(), - ts.ScriptTarget.ES2017, - /*setParentNodes */ true, - ); - const exportInfo = _getExportPathToExportedItems(sourceFile, omitExports); - return exportInfo; -} - -function _getExportPathToExportedItems(sf: ts.SourceFile, omitExports?: string[]): ExportInfo { - const exportPathToExportedItems: ExportPathToExportedItems = {}; - const exportPathOrder: string[] = []; - const exportsToOmit = _.isUndefined(omitExports) ? [] : omitExports; - processNode(sf); - - function processNode(node: ts.Node): void { - switch (node.kind) { - case ts.SyntaxKind.ExportDeclaration: { - const exportClause = (node as any).exportClause; - const exportPath = exportClause.parent.moduleSpecifier.text; - _.each(exportClause.elements, element => { - const exportItem = element.name.escapedText; - if (!_.includes(exportsToOmit, exportItem)) { - exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) - ? [exportItem] - : [...exportPathToExportedItems[exportPath], exportItem]; - } - }); - if (!_.isUndefined(exportPathToExportedItems[exportPath])) { - exportPathOrder.push(exportPath); - } - break; - } - - case ts.SyntaxKind.ExportKeyword: { - const foundNode: any = node; - const exportPath = './index'; - if (foundNode.parent && foundNode.parent.name) { - const exportItem = foundNode.parent.name.escapedText; - if (!_.includes(exportsToOmit, exportItem)) { - exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) - ? [exportItem] - : [...exportPathToExportedItems[exportPath], exportItem]; - } - } - if (!_.includes(exportPathOrder, exportPath) && !_.isUndefined(exportPathToExportedItems[exportPath])) { - exportPathOrder.push(exportPath); - } - break; - } - default: - // noop - break; - } - - ts.forEachChild(node, processNode); - } - const exportInfo = { - exportPathToExportedItems, - exportPathOrder, - }; - return exportInfo; -} -- cgit v1.2.3 From 3d1c8dfe06ba23696bb1fadb7754145da2f108be Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 13 Aug 2018 16:52:45 -0700 Subject: Remove old comment --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 870cbe17c..a7ac9765a 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -58,7 +58,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: if (isInternalToPkg) { const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); typeDocExtraFileIncludes.push(pathToInternalPkg); - return; // Right? + return; } const pathIfExists = pkgNameToPath[exportPath]; -- cgit v1.2.3 From 67666446bf6620bd83e4f90f6fffaac71c1bb00c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 13 Aug 2018 16:55:37 -0700 Subject: Add a check to make sure types part of the exported interface are also exported from the packages index.ts --- .../src/utils/doc_generate_and_upload_utils.ts | 54 ++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index a7ac9765a..84fb9d20c 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -19,6 +19,12 @@ interface ExportNameToTypedocNames { [exportName: string]: string[]; } +// TODO: Add the EXTERNAL_TYPE_TO_LINK mapping to the Doc JSON +const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { + BigNumber: 'http://mikemcl.github.io/bignumber.js', + Error: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L134', +}; + export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { const monorepoPackages = utils.getPackages(constants.monorepoRootPath); const pkg = _.find(monorepoPackages, monorepoPackage => { @@ -141,9 +147,24 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); }); - // TODO: Add extra metadata for Class properties that are class instances - // Look in file for imports of that class, get the import name and construct a link to - // it's definition on another docs page. + const allExportedItems = _.flatten(_.values(exportPathToExportedItems)); + const propertyName = ''; // Root has no property name + const referenceNamesWithDuplicates = getAllReferenceNames(propertyName, finalTypeDocOutput, []); + const referenceNames = _.uniq(referenceNamesWithDuplicates); + + const missingReferences: string[] = []; + _.each(referenceNames, referenceName => { + if (!_.includes(allExportedItems, referenceName) && _.isUndefined(EXTERNAL_TYPE_TO_LINK[referenceName])) { + missingReferences.push(referenceName); + } + }); + if (!_.isEmpty(missingReferences)) { + throw new Error( + `${packageName} package needs to export ${missingReferences.join( + ', ', + )} from it's index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, + ); + } // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON const docJson = { @@ -171,7 +192,34 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // Remove the generated docs directory await execAsync(`rm -rf ${jsonFilePath}`, { cwd, + +function getAllReferenceNames(propertyName: string, node: any, referenceNames: string[]): string[] { + let updatedReferenceNames = referenceNames; + if (!_.isObject(node)) { + return updatedReferenceNames; + } + // Some nodes of type reference are for subtypes, which we don't want to return. + // We therefore filter them out. + const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites']; + if ( + !_.isUndefined(node.type) && + _.isString(node.type) && + node.type === 'reference' && + _.isUndefined(node.typeArguments) && + !_.includes(SUB_TYPE_PROPERTY_NAMES, propertyName) + ) { + return [...referenceNames, node.name]; + } + _.each(node, (nodeValue, innerPropertyName) => { + if (_.isArray(nodeValue)) { + _.each(nodeValue, aNode => { + updatedReferenceNames = getAllReferenceNames(innerPropertyName, aNode, updatedReferenceNames); + }); + } else if (_.isObject(nodeValue)) { + updatedReferenceNames = getAllReferenceNames(innerPropertyName, nodeValue, updatedReferenceNames); + } }); + return updatedReferenceNames; } function findExportPathGivenTypedocName( -- cgit v1.2.3 From 1d9408a8e04aaea35bcf517fd3332b9bcc62bba0 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 14 Aug 2018 14:39:59 -0700 Subject: Fix additional merge conflicts --- .../src/utils/doc_generate_and_upload_utils.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 84fb9d20c..777d908fb 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -1,15 +1,14 @@ -import * as _ from 'lodash'; - -import { constants } from '../constants'; -import { utils } from './utils'; - import { readFileSync, writeFileSync } from 'fs'; +import * as _ from 'lodash'; import * as path from 'path'; import { exec as execAsync } from 'promisify-child-process'; import * as ts from 'typescript'; +import { constants } from '../constants'; import { ExportPathToExportedItems } from '../types'; +import { utils } from './utils'; + interface ExportInfo { exportPathToExportedItems: ExportPathToExportedItems; exportPathOrder: string[]; @@ -83,8 +82,8 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: } if (!_.startsWith(innerExportPath, './')) { throw new Error( - `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is - itself exported from an external package. To fix this, export the external dependency directly, + `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is + itself exported from an external package. To fix this, export the external dependency directly, not indirectly through ${innerExportPath}.`, ); } else { @@ -192,6 +191,8 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // Remove the generated docs directory await execAsync(`rm -rf ${jsonFilePath}`, { cwd, + }); +} function getAllReferenceNames(propertyName: string, node: any, referenceNames: string[]): string[] { let updatedReferenceNames = referenceNames; -- cgit v1.2.3 From 04e00e0c2849951b352692a8d8327160dc7475f8 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 14 Aug 2018 16:34:21 -0700 Subject: Improve missing type detection --- .../src/utils/doc_generate_and_upload_utils.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 777d908fb..dfaaf1c07 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -22,6 +22,10 @@ interface ExportNameToTypedocNames { const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { BigNumber: 'http://mikemcl.github.io/bignumber.js', Error: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L134', + Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262', + 'solc.StandardContractOutput': + 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description', + 'solc.CompilerSettings': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#input-description', }; export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { @@ -159,9 +163,9 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); if (!_.isEmpty(missingReferences)) { throw new Error( - `${packageName} package needs to export ${missingReferences.join( - ', ', - )} from it's index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, + `${packageName} package needs to export: \n${missingReferences.join( + '\n', + )} \nFrom it\'s index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, ); } @@ -201,7 +205,7 @@ function getAllReferenceNames(propertyName: string, node: any, referenceNames: s } // Some nodes of type reference are for subtypes, which we don't want to return. // We therefore filter them out. - const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites']; + const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites', 'extendedTypes']; if ( !_.isUndefined(node.type) && _.isString(node.type) && -- cgit v1.2.3 From 19e17ba12859a9cc94ce480fc6b29e28c711321e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 14 Aug 2018 16:34:48 -0700 Subject: Add ability to hide specific class constructors --- .../src/utils/doc_generate_and_upload_utils.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index dfaaf1c07..187358421 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -28,6 +28,16 @@ const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { 'solc.CompilerSettings': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#input-description', }; +const CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[] = [ + 'ERC20ProxyWrapper', + 'ERC20TokenWrapper', + 'ERC721ProxyWrapper', + 'ERC721TokenWrapper', + 'EtherTokenWrapper', + 'ExchangeWrapper', + 'ForwarderWrapper', +]; + export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { const monorepoPackages = utils.getPackages(constants.monorepoRootPath); const pkg = _.find(monorepoPackages, monorepoPackage => { @@ -146,6 +156,17 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: if (!_.includes(exportItems, child.name)) { delete finalTypeDocOutput.children[i].children[j]; } + if (child.kindString === 'Class' && _.includes(CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name)) { + const classChildren = typedocOutput.children[i].children[j].children; + _.each(classChildren, (classChild, k) => { + if (classChild.kindString === 'Constructor') { + delete finalTypeDocOutput.children[i].children[j].children[k]; + finalTypeDocOutput.children[i].children[j].children = _.compact( + finalTypeDocOutput.children[i].children[j].children, + ); + } + }); + } }); finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); }); -- cgit v1.2.3 From 267078ed6cea11aa8accc2336898694b77e8f169 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 14 Aug 2018 17:23:36 -0700 Subject: Remove duplicate Typescript import --- packages/monorepo-scripts/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index c8c74ebd2..a5b03ac80 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -64,8 +64,7 @@ "semver": "5.5.0", "semver-diff": "^2.1.0", "semver-sort": "0.0.4", - "typedoc": "0xProject/typedoc", - "typescript": "2.7.1" + "typedoc": "0xProject/typedoc" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From 83e3bb899ed88c8ac32331d2f1b533e52d5ad8cd Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 14 Aug 2018 17:41:03 -0700 Subject: Move purging private underscored items to the doc json generation phase --- .../src/utils/doc_generate_and_upload_utils.ts | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 187358421..2bc5441fc 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -143,7 +143,10 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: } }); - // For each entry, see if it was exported in index.ts. If not, remove it. + // For each entry, remove it if: + // - it was not exported in index.ts + // - the constructor is to be ignored + // - it begins with an underscore const exportPathToTypedocNames: ExportNameToTypedocNames = {}; _.each(typedocOutput.children, (file, i) => { const exportPath = findExportPathGivenTypedocName(exportPathToExportedItems, packageName, file.name); @@ -155,18 +158,22 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: _.each(file.children, (child, j) => { if (!_.includes(exportItems, child.name)) { delete finalTypeDocOutput.children[i].children[j]; + return; } - if (child.kindString === 'Class' && _.includes(CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name)) { - const classChildren = typedocOutput.children[i].children[j].children; - _.each(classChildren, (classChild, k) => { - if (classChild.kindString === 'Constructor') { - delete finalTypeDocOutput.children[i].children[j].children[k]; - finalTypeDocOutput.children[i].children[j].children = _.compact( - finalTypeDocOutput.children[i].children[j].children, - ); - } - }); - } + const innerChildren = typedocOutput.children[i].children[j].children; + _.each(innerChildren, (innerChild, k) => { + const isHiddenConstructor = + child.kindString === 'Class' && + _.includes(CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name) && + innerChild.kindString === 'Constructor'; + const isPrivate = _.startsWith(innerChild.name, '_'); + if (isHiddenConstructor || isPrivate) { + delete finalTypeDocOutput.children[i].children[j].children[k]; + finalTypeDocOutput.children[i].children[j].children = _.compact( + finalTypeDocOutput.children[i].children[j].children, + ); + } + }); }); finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); }); -- cgit v1.2.3 From 3b8a343711e0b23a453a1466411e2b9ca68eb0b2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 14 Aug 2018 17:55:38 -0700 Subject: Add version to our custom DocJson format --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 2bc5441fc..d791b010f 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -18,7 +18,8 @@ interface ExportNameToTypedocNames { [exportName: string]: string[]; } -// TODO: Add the EXTERNAL_TYPE_TO_LINK mapping to the Doc JSON +const DOC_JSON_VERSION = '0.0.1'; + const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { BigNumber: 'http://mikemcl.github.io/bignumber.js', Error: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L134', @@ -199,6 +200,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON const docJson = { + version: DOC_JSON_VERSION, metadata: { exportPathToTypedocNames, exportPathOrder, -- cgit v1.2.3 From a8d44ccc48a7177e749f534a237afb7b9c0f2f2b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 15 Aug 2018 11:36:45 -0700 Subject: Move external types to link mapping to doc generation util and refactor typedocUtils to be a class to avoid excessive param passing --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index d791b010f..ca3df2c74 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -27,6 +27,7 @@ const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { 'solc.StandardContractOutput': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description', 'solc.CompilerSettings': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#input-description', + Schema: 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', }; const CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[] = [ -- cgit v1.2.3 From 6e74d1519b2071b8c8c19639b0e9726a278d8a84 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 15 Aug 2018 11:37:06 -0700 Subject: Add externalTypeToLink to docJson --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index ca3df2c74..be2d9f7e5 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -205,6 +205,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: metadata: { exportPathToTypedocNames, exportPathOrder, + externalTypeToLink: EXTERNAL_TYPE_TO_LINK, }, typedocJson: finalTypeDocOutput, }; -- cgit v1.2.3 From 9e7657ac5db596ff8dacf1c37784be2e9e7f87a6 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 15 Aug 2018 16:38:30 -0700 Subject: Improve Error external link --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index be2d9f7e5..b51b17db1 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -22,7 +22,7 @@ const DOC_JSON_VERSION = '0.0.1'; const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { BigNumber: 'http://mikemcl.github.io/bignumber.js', - Error: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L134', + Error: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error', Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262', 'solc.StandardContractOutput': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description', -- cgit v1.2.3 From baab0f27b543f8f17bad0e3a40b803763236edb9 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 15 Aug 2018 16:50:23 -0700 Subject: Check for superfluous types in a packages index.ts and throw if they exist --- .../src/utils/doc_generate_and_upload_utils.ts | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index b51b17db1..b236c299f 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -185,6 +185,16 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: const referenceNamesWithDuplicates = getAllReferenceNames(propertyName, finalTypeDocOutput, []); const referenceNames = _.uniq(referenceNamesWithDuplicates); + const exportedTypes = getAllTypeNames(finalTypeDocOutput, []); + const excessiveReferences = _.difference(exportedTypes, referenceNames); + if (!_.isEmpty(excessiveReferences)) { + throw new Error( + `${packageName} package exports BUT does not need: \n${excessiveReferences.join( + '\n', + )} \nin it\'s index.ts. Remove them then try again.`, + ); + } + const missingReferences: string[] = []; _.each(referenceNames, referenceName => { if (!_.includes(allExportedItems, referenceName) && _.isUndefined(EXTERNAL_TYPE_TO_LINK[referenceName])) { @@ -230,6 +240,27 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: }); } +function getAllTypeNames(node: any, typeNames: string[]): string[] { + if (!_.isObject(node)) { + return typeNames; + } + const typeKindStrings = ['Interface', 'Enumeration', 'Type alias']; + if (_.includes(typeKindStrings, node.kindString)) { + return [...typeNames, node.name]; + } + let updatedTypeNames = typeNames; + _.each(node, nodeValue => { + if (_.isArray(nodeValue)) { + _.each(nodeValue, aNode => { + updatedTypeNames = getAllTypeNames(aNode, updatedTypeNames); + }); + } else if (_.isObject(nodeValue)) { + updatedTypeNames = getAllTypeNames(nodeValue, updatedTypeNames); + } + }); + return updatedTypeNames; +} + function getAllReferenceNames(propertyName: string, node: any, referenceNames: string[]): string[] { let updatedReferenceNames = referenceNames; if (!_.isObject(node)) { -- cgit v1.2.3 From ae7bce767442f127961180f7d101265dcbc8ed80 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 16 Aug 2018 13:56:29 -0700 Subject: Add links for external dep exports to docJson --- .../src/utils/doc_generate_and_upload_utils.ts | 45 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index b236c299f..e866d5bbc 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -30,6 +30,16 @@ const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { Schema: 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', }; +/** + * If a 0x package re-exports an external package, we should add a link to it's exported items here + */ +const EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string } = { + Web3ProviderEngine: 'https://www.npmjs.com/package/web3-provider-engine', + BigNumber: 'https://www.npmjs.com/package/bignumber.js', + Schema: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/index.d.ts#L49', + ValidatorResult: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/helpers.js#L31', +}; + const CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[] = [ 'ERC20ProxyWrapper', 'ERC20TokenWrapper', @@ -67,10 +77,9 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: } const pkgNameToPath: { [name: string]: string } = {}; - _.each(monorepoPackages, pkg => { - pkgNameToPath[pkg.packageJson.name] = pkg.location; - }); + _.each(monorepoPackages, p => (pkgNameToPath[p.packageJson.name] = p.location)); + const externalExports: string[] = []; // For each dep that is another one of our monorepo packages, we fetch it's index.ts // and see which specific files we must pass to TypeDoc. let typeDocExtraFileIncludes: string[] = []; @@ -84,6 +93,9 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: const pathIfExists = pkgNameToPath[exportPath]; if (_.isUndefined(pathIfExists)) { + _.each(exportedItems, exportedItem => { + externalExports.push(exportedItem); + }); return; // It's an external package } @@ -209,6 +221,24 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: ); } + const externalExportsToLink: { [externalExport: string]: string } = {}; + const externalExportsWithoutLinks: string[] = []; + _.each(externalExports, externalExport => { + const linkIfExists = EXTERNAL_EXPORT_TO_LINK[externalExport]; + if (_.isUndefined(linkIfExists)) { + externalExportsWithoutLinks.push(externalExport); + return; + } + externalExportsToLink[externalExport] = linkIfExists; + }); + if (!_.isEmpty(externalExportsWithoutLinks)) { + throw new Error( + `Found the following external exports in ${packageName}'s index.ts:\n ${externalExportsWithoutLinks.join( + '\n', + )}\nThey are missing from the EXTERNAL_EXPORT_TO_LINK mapping. Add them and try again.`, + ); + } + // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON const docJson = { version: DOC_JSON_VERSION, @@ -216,6 +246,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: exportPathToTypedocNames, exportPathOrder, externalTypeToLink: EXTERNAL_TYPE_TO_LINK, + externalExportsToLink, }, typedocJson: finalTypeDocOutput, }; @@ -367,9 +398,15 @@ function _getExportPathToExportedItems(sf: ts.SourceFile, omitExports?: string[] case ts.SyntaxKind.ExportKeyword: { const foundNode: any = node; - const exportPath = './index'; + let exportPath = './index'; if (foundNode.parent && foundNode.parent.name) { const exportItem = foundNode.parent.name.escapedText; + const isExportImportRequireStatement = !_.isUndefined( + _.get(foundNode, 'parent.moduleReference.expression.text'), + ); + if (isExportImportRequireStatement) { + exportPath = foundNode.parent.moduleReference.expression.text; + } if (!_.includes(exportsToOmit, exportItem)) { exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) ? [exportItem] -- cgit v1.2.3 From 8e3df2b5aeac9d6776640be1248863055c75cf4a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 16 Aug 2018 14:57:45 -0700 Subject: Render external dep exports --- .../monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index e866d5bbc..b4911c84b 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -221,7 +221,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: ); } - const externalExportsToLink: { [externalExport: string]: string } = {}; + const externalExportToLink: { [externalExport: string]: string } = {}; const externalExportsWithoutLinks: string[] = []; _.each(externalExports, externalExport => { const linkIfExists = EXTERNAL_EXPORT_TO_LINK[externalExport]; @@ -229,7 +229,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: externalExportsWithoutLinks.push(externalExport); return; } - externalExportsToLink[externalExport] = linkIfExists; + externalExportToLink[externalExport] = linkIfExists; }); if (!_.isEmpty(externalExportsWithoutLinks)) { throw new Error( @@ -246,7 +246,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: exportPathToTypedocNames, exportPathOrder, externalTypeToLink: EXTERNAL_TYPE_TO_LINK, - externalExportsToLink, + externalExportToLink, }, typedocJson: finalTypeDocOutput, }; -- cgit v1.2.3 From f7375fca98c01093f34f916f93f9bfe76278b6af Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 16 Aug 2018 17:02:37 -0700 Subject: Move doc configs to a separate file --- packages/monorepo-scripts/src/doc_gen_configs.ts | 33 +++++++++++++ packages/monorepo-scripts/src/types.ts | 16 ++++++ .../src/utils/doc_generate_and_upload_utils.ts | 57 ++++------------------ 3 files changed, 59 insertions(+), 47 deletions(-) create mode 100644 packages/monorepo-scripts/src/doc_gen_configs.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts new file mode 100644 index 000000000..fd95863c3 --- /dev/null +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -0,0 +1,33 @@ +import { DocGenConfigs } from './types'; + +export const docGenConfigs: DocGenConfigs = { + DOC_JSON_VERSION: '0.0.1', + EXTERNAL_TYPE_TO_LINK: { + BigNumber: 'http://mikemcl.github.io/bignumber.js', + Error: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error', + Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262', + 'solc.StandardContractOutput': + 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description', + 'solc.CompilerSettings': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#input-description', + Schema: + 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', + }, + /** + * If a 0x package re-exports an external package, we should add a link to it's exported items here + */ + EXTERNAL_EXPORT_TO_LINK: { + Web3ProviderEngine: 'https://www.npmjs.com/package/web3-provider-engine', + BigNumber: 'https://www.npmjs.com/package/bignumber.js', + Schema: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/index.d.ts#L49', + ValidatorResult: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/helpers.js#L31', + }, + CLASSES_WITH_HIDDEN_CONSTRUCTORS: [ + 'ERC20ProxyWrapper', + 'ERC20TokenWrapper', + 'ERC721ProxyWrapper', + 'ERC721TokenWrapper', + 'EtherTokenWrapper', + 'ExchangeWrapper', + 'ForwarderWrapper', + ], +}; diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index 4d4600abf..5f6a6c707 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -50,6 +50,22 @@ export interface Package { packageJson: PackageJSON; } +export interface DocGenConfigs { + DOC_JSON_VERSION: string; + EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string }; + EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string }; + CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[]; +} + export interface ExportPathToExportedItems { [pkgName: string]: string[]; } + +export interface ExportInfo { + exportPathToExportedItems: ExportPathToExportedItems; + exportPathOrder: string[]; +} + +export interface ExportNameToTypedocNames { + [exportName: string]: string[]; +} diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index b4911c84b..0d9c47932 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -5,51 +5,11 @@ import { exec as execAsync } from 'promisify-child-process'; import * as ts from 'typescript'; import { constants } from '../constants'; -import { ExportPathToExportedItems } from '../types'; +import { docGenConfigs } from '../doc_gen_configs'; +import { ExportInfo, ExportNameToTypedocNames, ExportPathToExportedItems } from '../types'; import { utils } from './utils'; -interface ExportInfo { - exportPathToExportedItems: ExportPathToExportedItems; - exportPathOrder: string[]; -} - -interface ExportNameToTypedocNames { - [exportName: string]: string[]; -} - -const DOC_JSON_VERSION = '0.0.1'; - -const EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string } = { - BigNumber: 'http://mikemcl.github.io/bignumber.js', - Error: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error', - Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262', - 'solc.StandardContractOutput': - 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description', - 'solc.CompilerSettings': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#input-description', - Schema: 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', -}; - -/** - * If a 0x package re-exports an external package, we should add a link to it's exported items here - */ -const EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string } = { - Web3ProviderEngine: 'https://www.npmjs.com/package/web3-provider-engine', - BigNumber: 'https://www.npmjs.com/package/bignumber.js', - Schema: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/index.d.ts#L49', - ValidatorResult: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/helpers.js#L31', -}; - -const CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[] = [ - 'ERC20ProxyWrapper', - 'ERC20TokenWrapper', - 'ERC721ProxyWrapper', - 'ERC721TokenWrapper', - 'EtherTokenWrapper', - 'ExchangeWrapper', - 'ForwarderWrapper', -]; - export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { const monorepoPackages = utils.getPackages(constants.monorepoRootPath); const pkg = _.find(monorepoPackages, monorepoPackage => { @@ -178,7 +138,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: _.each(innerChildren, (innerChild, k) => { const isHiddenConstructor = child.kindString === 'Class' && - _.includes(CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name) && + _.includes(docGenConfigs.CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name) && innerChild.kindString === 'Constructor'; const isPrivate = _.startsWith(innerChild.name, '_'); if (isHiddenConstructor || isPrivate) { @@ -209,7 +169,10 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: const missingReferences: string[] = []; _.each(referenceNames, referenceName => { - if (!_.includes(allExportedItems, referenceName) && _.isUndefined(EXTERNAL_TYPE_TO_LINK[referenceName])) { + if ( + !_.includes(allExportedItems, referenceName) && + _.isUndefined(docGenConfigs.EXTERNAL_TYPE_TO_LINK[referenceName]) + ) { missingReferences.push(referenceName); } }); @@ -224,7 +187,7 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: const externalExportToLink: { [externalExport: string]: string } = {}; const externalExportsWithoutLinks: string[] = []; _.each(externalExports, externalExport => { - const linkIfExists = EXTERNAL_EXPORT_TO_LINK[externalExport]; + const linkIfExists = docGenConfigs.EXTERNAL_EXPORT_TO_LINK[externalExport]; if (_.isUndefined(linkIfExists)) { externalExportsWithoutLinks.push(externalExport); return; @@ -241,11 +204,11 @@ export async function generateAndUploadDocsAsync(packageName: string, isStaging: // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON const docJson = { - version: DOC_JSON_VERSION, + version: docGenConfigs.DOC_JSON_VERSION, metadata: { exportPathToTypedocNames, exportPathOrder, - externalTypeToLink: EXTERNAL_TYPE_TO_LINK, + externalTypeToLink: docGenConfigs.EXTERNAL_TYPE_TO_LINK, externalExportToLink, }, typedocJson: finalTypeDocOutput, -- cgit v1.2.3 From 05ce0024352f2198a3744d62d9532a7e729ef5fa Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 17 Aug 2018 12:53:27 -0700 Subject: Refactor DocGenerateAndUploadUtils to be a class, and decompose large methods for readability --- .../src/doc_generate_and_upload.ts | 5 +- packages/monorepo-scripts/src/publish.ts | 9 +- .../src/utils/doc_generate_and_upload_utils.ts | 761 ++++++++++++--------- 3 files changed, 427 insertions(+), 348 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index e0e7e1bb5..602247972 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -1,6 +1,6 @@ import * as yargs from 'yargs'; -import { generateAndUploadDocsAsync } from './utils/doc_generate_and_upload_utils'; +import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils'; const args = yargs .option('package', { @@ -19,5 +19,6 @@ const args = yargs const packageName = args.package; const isStaging = args.isStaging; - await generateAndUploadDocsAsync(packageName, isStaging); + const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageName, isStaging); + await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); })(); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index bb2dd60c1..6691fd3c1 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -13,9 +13,9 @@ import { constants } from './constants'; import { Package, PackageToNextVersion, VersionChangelog } from './types'; import { changelogUtils } from './utils/changelog_utils'; import { configs } from './utils/configs'; -import { utils } from './utils/utils'; +import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils'; import { publishReleaseNotesAsync } from './utils/github_release_utils'; -import { generateAndUploadDocsAsync } from './utils/doc_generate_and_upload_utils'; +import { utils } from './utils/utils'; const DOC_GEN_COMMAND = 'docs:json'; const NPM_NAMESPACE = '@0xproject/'; @@ -81,11 +81,12 @@ async function confirmAsync(message: string): Promise { process.exit(1); }); -async function generateAndUploadDocJsonsAsync(updatedPublicPackages: Package[], isStaging: boolean) { +async function generateAndUploadDocJsonsAsync(updatedPublicPackages: Package[], isStaging: boolean): Promise { for (const pkg of updatedPublicPackages) { const packageName = pkg.packageJson.name; const nameWithoutPrefix = packageName.replace('@0xproject/', ''); - await generateAndUploadDocsAsync(nameWithoutPrefix, isStaging); + const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging); + await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); } } diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 0d9c47932..a2902d1e4 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -6,391 +6,468 @@ import * as ts from 'typescript'; import { constants } from '../constants'; import { docGenConfigs } from '../doc_gen_configs'; -import { ExportInfo, ExportNameToTypedocNames, ExportPathToExportedItems } from '../types'; +import { ExportInfo, ExportNameToTypedocNames, ExportPathToExportedItems, PackageJSON } from '../types'; import { utils } from './utils'; -export async function generateAndUploadDocsAsync(packageName: string, isStaging: boolean): Promise { - const monorepoPackages = utils.getPackages(constants.monorepoRootPath); - const pkg = _.find(monorepoPackages, monorepoPackage => { - return _.includes(monorepoPackage.packageJson.name, packageName); - }); - if (_.isUndefined(pkg)) { - throw new Error(`Couldn't find a package.json for ${packageName}`); +export class DocGenerateAndUploadUtils { + private _isStaging: boolean; + private _packageName: string; + private _omitExports: string[]; + private _packagePath: string; + private _exportPathToExportedItems: ExportPathToExportedItems; + private _exportPathOrder: string[]; + private _monoRepoPkgNameToPath: { [name: string]: string }; + private _packageJson: PackageJSON; + /** + * Recursively iterate over the TypeDoc JSON object and find all type names + */ + private static _getAllTypeNames(node: any, typeNames: string[]): string[] { + if (!_.isObject(node)) { + return typeNames; + } + const typeKindStrings = ['Interface', 'Enumeration', 'Type alias']; + if (_.includes(typeKindStrings, node.kindString)) { + return [...typeNames, node.name]; + } + let updatedTypeNames = typeNames; + _.each(node, nodeValue => { + if (_.isArray(nodeValue)) { + _.each(nodeValue, aNode => { + updatedTypeNames = DocGenerateAndUploadUtils._getAllTypeNames(aNode, updatedTypeNames); + }); + } else if (_.isObject(nodeValue)) { + updatedTypeNames = DocGenerateAndUploadUtils._getAllTypeNames(nodeValue, updatedTypeNames); + } + }); + return updatedTypeNames; } + /** + * Recursively iterate over the TypeDoc JSON object and find all reference names (i.e types, classNames, + * objectLiteral names, etc...) + */ + private static _getAllReferenceNames(propertyName: string, node: any, referenceNames: string[]): string[] { + if (!_.isObject(node)) { + return referenceNames; + } - const packageJson = pkg.packageJson; - const omitExports = _.get(packageJson, 'config.postpublish.omitExports', []); + let updatedReferenceNames = referenceNames; + // Some nodes of type reference are for subtypes, which we don't want to return. + // We therefore filter them out. + const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites', 'extendedTypes']; + if ( + !_.isUndefined(node.type) && + _.isString(node.type) && + node.type === 'reference' && + _.isUndefined(node.typeArguments) && + !_.includes(SUB_TYPE_PROPERTY_NAMES, propertyName) + ) { + updatedReferenceNames = _.uniq([...referenceNames, node.name]); + return updatedReferenceNames; + } + _.each(node, (nodeValue, innerPropertyName) => { + if (_.isArray(nodeValue)) { + _.each(nodeValue, aNode => { + updatedReferenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( + innerPropertyName, + aNode, + updatedReferenceNames, + ); + }); + } else if (_.isObject(nodeValue)) { + updatedReferenceNames = updatedReferenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( + innerPropertyName, + nodeValue, + updatedReferenceNames, + ); + } + }); + return _.uniq(updatedReferenceNames); + } + private static _getExportPathToExportedItems(filePath: string, omitExports?: string[]): ExportInfo { + const sourceFile = ts.createSourceFile( + 'indexFile', + readFileSync(filePath).toString(), + ts.ScriptTarget.ES2017, + /*setParentNodes */ true, + ); + const exportPathToExportedItems: ExportPathToExportedItems = {}; + const exportPathOrder: string[] = []; + const exportsToOmit = _.isUndefined(omitExports) ? [] : omitExports; - const pathToPackage = `${constants.monorepoRootPath}/packages/${packageName}`; - const indexPath = `${pathToPackage}/src/index.ts`; - const { exportPathToExportedItems, exportPathOrder } = getExportPathToExportedItems(indexPath, omitExports); + processNode(sourceFile); - const shouldPublishDocs = !!_.get(packageJson, 'config.postpublish.shouldPublishDocs'); - if (!shouldPublishDocs) { - utils.log( - `GENERATE_UPLOAD_DOCS: ${ - packageJson.name - } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, - ); - return; - } + function processNode(node: ts.Node): void { + switch (node.kind) { + case ts.SyntaxKind.ExportDeclaration: { + const exportClause = (node as any).exportClause; + const exportPath = exportClause.parent.moduleSpecifier.text; + _.each(exportClause.elements, element => { + const exportItem = element.name.escapedText; + if (!_.includes(exportsToOmit, exportItem)) { + exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) + ? [exportItem] + : [...exportPathToExportedItems[exportPath], exportItem]; + } + }); + if (!_.isUndefined(exportPathToExportedItems[exportPath])) { + exportPathOrder.push(exportPath); + } + break; + } - const pkgNameToPath: { [name: string]: string } = {}; - _.each(monorepoPackages, p => (pkgNameToPath[p.packageJson.name] = p.location)); + case ts.SyntaxKind.ExportKeyword: { + const foundNode: any = node; + let exportPath = './index'; + if (foundNode.parent && foundNode.parent.name) { + const exportItem = foundNode.parent.name.escapedText; + const isExportImportRequireStatement = !_.isUndefined( + _.get(foundNode, 'parent.moduleReference.expression.text'), + ); + if (isExportImportRequireStatement) { + exportPath = foundNode.parent.moduleReference.expression.text; + } + if (!_.includes(exportsToOmit, exportItem)) { + exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) + ? [exportItem] + : [...exportPathToExportedItems[exportPath], exportItem]; + } + } + if ( + !_.includes(exportPathOrder, exportPath) && + !_.isUndefined(exportPathToExportedItems[exportPath]) + ) { + exportPathOrder.push(exportPath); + } + break; + } + default: + // noop + break; + } - const externalExports: string[] = []; - // For each dep that is another one of our monorepo packages, we fetch it's index.ts - // and see which specific files we must pass to TypeDoc. - let typeDocExtraFileIncludes: string[] = []; - _.each(exportPathToExportedItems, (exportedItems, exportPath) => { - const isInternalToPkg = _.startsWith(exportPath, '.'); - if (isInternalToPkg) { - const pathToInternalPkg = path.join(pathToPackage, 'src', `${exportPath}.ts`); - typeDocExtraFileIncludes.push(pathToInternalPkg); - return; + ts.forEachChild(node, processNode); } + const exportInfo = { + exportPathToExportedItems, + exportPathOrder, + }; + return exportInfo; + } + constructor(packageName: string, isStaging: boolean) { + this._isStaging = isStaging; + this._packageName = packageName; + this._packagePath = `${constants.monorepoRootPath}/packages/${packageName}`; - const pathIfExists = pkgNameToPath[exportPath]; - if (_.isUndefined(pathIfExists)) { - _.each(exportedItems, exportedItem => { - externalExports.push(exportedItem); - }); - return; // It's an external package - } + this._monoRepoPkgNameToPath = {}; + const monorepoPackages = utils.getPackages(constants.monorepoRootPath); + _.each(monorepoPackages, p => (this._monoRepoPkgNameToPath[p.packageJson.name] = p.location)); - const typeDocSourceIncludes = new Set(); - const pathToIndex = `${pathIfExists}/src/index.ts`; - const exportInfo = getExportPathToExportedItems(pathToIndex); - const innerExportPathToExportedItems = exportInfo.exportPathToExportedItems; - _.each(exportedItems, exportName => { - _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { - if (!_.includes(innerExportItems, exportName)) { - return; - } - if (!_.startsWith(innerExportPath, './')) { - throw new Error( - `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is - itself exported from an external package. To fix this, export the external dependency directly, - not indirectly through ${innerExportPath}.`, - ); - } else { - const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); - typeDocSourceIncludes.add(absoluteSrcPath); - } - }); + const pkg = _.find(monorepoPackages, monorepoPackage => { + return _.includes(monorepoPackage.packageJson.name, packageName); }); - // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types - // directly, meaning no internal paths will exist to follow. Other packages also have direct exports - // in their index.ts, so we always add it to the source files passed to TypeDoc - if (typeDocSourceIncludes.size === 0) { - typeDocSourceIncludes.add(pathToIndex); + if (_.isUndefined(pkg)) { + throw new Error(`Couldn't find a package.json for ${packageName}`); } + this._packageJson = pkg.packageJson; + this._omitExports = _.get(this._packageJson, 'config.postpublish.omitExports', []); - typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; - }); - - // Generate Typedoc JSON file - typeDocExtraFileIncludes.push(path.join(pathToPackage, 'src', 'globals.d.ts')); - const jsonFilePath = path.join(pathToPackage, 'generated_docs', 'index.json'); - const projectFiles = typeDocExtraFileIncludes.join(' '); - const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); - // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the - // packages root dir, does not work. It only works when called via a `package.json` script located - // in the package's root. - await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { - cwd, - }); + const indexPath = `${this._packagePath}/src/index.ts`; + const exportInfo = DocGenerateAndUploadUtils._getExportPathToExportedItems(indexPath, this._omitExports); + this._exportPathToExportedItems = exportInfo.exportPathToExportedItems; + this._exportPathOrder = exportInfo.exportPathOrder; - // Unfortunately TypeDoc children names will only be prefixed with the name of the package _if_ we passed - // TypeDoc files outside of the packages root path (i.e this package exports another package found in our - // monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add - // it here when necessary. - const typedocOutputString = readFileSync(jsonFilePath).toString(); - const typedocOutput = JSON.parse(typedocOutputString); - const finalTypeDocOutput = _.clone(typedocOutput); - _.each(typedocOutput.children, (child, i) => { - if (!_.includes(child.name, '/src/')) { - const nameWithoutQuotes = child.name.replace(/"/g, ''); - const standardizedName = `"${packageName}/src/${nameWithoutQuotes}"`; - finalTypeDocOutput.children[i].name = standardizedName; + const shouldPublishDocs = !!_.get(this._packageJson, 'config.postpublish.shouldPublishDocs'); + if (!shouldPublishDocs) { + utils.log( + `GENERATE_UPLOAD_DOCS: ${ + this._packageJson.name + } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, + ); + return; } - }); + } + public async generateAndUploadDocsAsync(): Promise { + // For each dep that is another one of our monorepo packages, we fetch it's index.ts + // and see which specific files we must pass to TypeDoc, in order to generate a Doc JSON + // the includes everything exported by the public interface. + const typeDocExtraFileIncludes: string[] = this._getTypeDocFileIncludesForPackage(); - // For each entry, remove it if: - // - it was not exported in index.ts - // - the constructor is to be ignored - // - it begins with an underscore - const exportPathToTypedocNames: ExportNameToTypedocNames = {}; - _.each(typedocOutput.children, (file, i) => { - const exportPath = findExportPathGivenTypedocName(exportPathToExportedItems, packageName, file.name); - exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) - ? [file.name] - : [...exportPathToTypedocNames[exportPath], file.name]; + // In order to avoid TS errors, we need to pass TypeDoc the package's global.d.ts file + typeDocExtraFileIncludes.push(path.join(this._packagePath, 'src', 'globals.d.ts')); - const exportItems = exportPathToExportedItems[exportPath]; - _.each(file.children, (child, j) => { - if (!_.includes(exportItems, child.name)) { - delete finalTypeDocOutput.children[i].children[j]; - return; - } - const innerChildren = typedocOutput.children[i].children[j].children; - _.each(innerChildren, (innerChild, k) => { - const isHiddenConstructor = - child.kindString === 'Class' && - _.includes(docGenConfigs.CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name) && - innerChild.kindString === 'Constructor'; - const isPrivate = _.startsWith(innerChild.name, '_'); - if (isHiddenConstructor || isPrivate) { - delete finalTypeDocOutput.children[i].children[j].children[k]; - finalTypeDocOutput.children[i].children[j].children = _.compact( - finalTypeDocOutput.children[i].children[j].children, - ); - } - }); + const jsonFilePath = path.join(this._packagePath, 'generated_docs', 'index.json'); + const projectFiles = typeDocExtraFileIncludes.join(' '); + const cwd = path.join(constants.monorepoRootPath, 'packages', this._packageName); + // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the + // packages root dir, does not work. It only works when called via a `package.json` script located + // in the package's root. + await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { + cwd, }); - finalTypeDocOutput.children[i].children = _.compact(finalTypeDocOutput.children[i].children); - }); - const allExportedItems = _.flatten(_.values(exportPathToExportedItems)); - const propertyName = ''; // Root has no property name - const referenceNamesWithDuplicates = getAllReferenceNames(propertyName, finalTypeDocOutput, []); - const referenceNames = _.uniq(referenceNamesWithDuplicates); + const typedocOutputString = readFileSync(jsonFilePath).toString(); + const typedocOutput = JSON.parse(typedocOutputString); + let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput); + modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput); - const exportedTypes = getAllTypeNames(finalTypeDocOutput, []); - const excessiveReferences = _.difference(exportedTypes, referenceNames); - if (!_.isEmpty(excessiveReferences)) { - throw new Error( - `${packageName} package exports BUT does not need: \n${excessiveReferences.join( - '\n', - )} \nin it\'s index.ts. Remove them then try again.`, - ); - } + const propertyName = ''; // Root has no property name + const referenceNames = DocGenerateAndUploadUtils._getAllReferenceNames(propertyName, modifiedTypedocOutput, []); + this._lookForUnusedExportedTypesThrowIfExists(referenceNames, modifiedTypedocOutput); + this._lookForMissingReferenceExportsThrowIfExists(referenceNames); - const missingReferences: string[] = []; - _.each(referenceNames, referenceName => { - if ( - !_.includes(allExportedItems, referenceName) && - _.isUndefined(docGenConfigs.EXTERNAL_TYPE_TO_LINK[referenceName]) - ) { - missingReferences.push(referenceName); + // Some of our packages re-export external package exports in their index.ts + // Typedoc is incapable of rendering these packages, so we need to special-case them + const externalExportToLink: { [externalExport: string]: string } = {}; + const externalExportsWithoutLinks: string[] = []; + const externalExports: string[] = this._getAllExternalExports(); + _.each(externalExports, externalExport => { + const linkIfExists = docGenConfigs.EXTERNAL_EXPORT_TO_LINK[externalExport]; + if (_.isUndefined(linkIfExists)) { + externalExportsWithoutLinks.push(externalExport); + return; + } + externalExportToLink[externalExport] = linkIfExists; + }); + if (!_.isEmpty(externalExportsWithoutLinks)) { + throw new Error( + `Found the following external exports in ${ + this._packageName + }'s index.ts:\n ${externalExportsWithoutLinks.join( + '\n', + )}\nThey are missing from the EXTERNAL_EXPORT_TO_LINK mapping. Add them and try again.`, + ); } - }); - if (!_.isEmpty(missingReferences)) { - throw new Error( - `${packageName} package needs to export: \n${missingReferences.join( - '\n', - )} \nFrom it\'s index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, - ); - } - const externalExportToLink: { [externalExport: string]: string } = {}; - const externalExportsWithoutLinks: string[] = []; - _.each(externalExports, externalExport => { - const linkIfExists = docGenConfigs.EXTERNAL_EXPORT_TO_LINK[externalExport]; - if (_.isUndefined(linkIfExists)) { - externalExportsWithoutLinks.push(externalExport); - return; - } - externalExportToLink[externalExport] = linkIfExists; - }); - if (!_.isEmpty(externalExportsWithoutLinks)) { - throw new Error( - `Found the following external exports in ${packageName}'s index.ts:\n ${externalExportsWithoutLinks.join( - '\n', - )}\nThey are missing from the EXTERNAL_EXPORT_TO_LINK mapping. Add them and try again.`, - ); - } + const exportPathToTypedocNames: ExportNameToTypedocNames = {}; + _.each(modifiedTypedocOutput.children, file => { + const exportPath = this._findExportPathGivenTypedocName(file.name); + exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) + ? [file.name] + : [...exportPathToTypedocNames[exportPath], file.name]; + }); - // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON - const docJson = { - version: docGenConfigs.DOC_JSON_VERSION, - metadata: { - exportPathToTypedocNames, - exportPathOrder, - externalTypeToLink: docGenConfigs.EXTERNAL_TYPE_TO_LINK, - externalExportToLink, - }, - typedocJson: finalTypeDocOutput, - }; + // Since we need additional metadata included in the doc JSON, we nest the TypeDoc JSON + // within our own custom, versioned docsJson format. + const docJson = { + version: docGenConfigs.DOC_JSON_VERSION, + metadata: { + exportPathToTypedocNames, + exportPathOrder: this._exportPathOrder, + externalTypeToLink: docGenConfigs.EXTERNAL_TYPE_TO_LINK, + externalExportToLink, + }, + typedocJson: modifiedTypedocOutput, + }; + writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); - // Write modified TypeDoc JSON, without all the unexported stuff - writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); + const fileName = `v${this._packageJson.version}.json`; + utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); - const fileName = `v${packageJson.version}.json`; - utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); - const S3BucketPath = isStaging ? `s3://staging-doc-jsons/${packageName}/` : `s3://doc-jsons/${packageName}/`; - const s3Url = `${S3BucketPath}${fileName}`; - await execAsync( - `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, - { + const S3BucketPath = this._isStaging + ? `s3://staging-doc-jsons/${this._packageName}/` + : `s3://doc-jsons/${this._packageName}/`; + const s3Url = `${S3BucketPath}${fileName}`; + await execAsync( + `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, + { + cwd, + }, + ); + utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); + // Remove the generated docs directory + await execAsync(`rm -rf ${jsonFilePath}`, { cwd, - }, - ); - utils.log(`GENERATE_UPLOAD_DOCS: Docs uploaded to S3 bucket: ${S3BucketPath}`); - // Remove the generated docs directory - await execAsync(`rm -rf ${jsonFilePath}`, { - cwd, - }); -} - -function getAllTypeNames(node: any, typeNames: string[]): string[] { - if (!_.isObject(node)) { - return typeNames; + }); } - const typeKindStrings = ['Interface', 'Enumeration', 'Type alias']; - if (_.includes(typeKindStrings, node.kindString)) { - return [...typeNames, node.name]; + /** + * Look for types that are used by the public interface but are missing from a package's index.ts + */ + private _lookForMissingReferenceExportsThrowIfExists(referenceNames: string[]): void { + const allExportedItems = _.flatten(_.values(this._exportPathToExportedItems)); + const missingReferences: string[] = []; + _.each(referenceNames, referenceName => { + if ( + !_.includes(allExportedItems, referenceName) && + _.isUndefined(docGenConfigs.EXTERNAL_TYPE_TO_LINK[referenceName]) + ) { + missingReferences.push(referenceName); + } + }); + if (!_.isEmpty(missingReferences)) { + throw new Error( + `${this._packageName} package needs to export: \n${missingReferences.join( + '\n', + )} \nFrom it\'s index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, + ); + } } - let updatedTypeNames = typeNames; - _.each(node, nodeValue => { - if (_.isArray(nodeValue)) { - _.each(nodeValue, aNode => { - updatedTypeNames = getAllTypeNames(aNode, updatedTypeNames); - }); - } else if (_.isObject(nodeValue)) { - updatedTypeNames = getAllTypeNames(nodeValue, updatedTypeNames); + /** + * Look for exported types that are not used by the package's public interface + */ + private _lookForUnusedExportedTypesThrowIfExists(referenceNames: string[], typedocOutput: any): void { + const exportedTypes = DocGenerateAndUploadUtils._getAllTypeNames(typedocOutput, []); + const excessiveReferences = _.difference(exportedTypes, referenceNames); + if (!_.isEmpty(excessiveReferences)) { + throw new Error( + `${this._packageName} package exports BUT does not need: \n${excessiveReferences.join( + '\n', + )} \nin it\'s index.ts. Remove them then try again.`, + ); } - }); - return updatedTypeNames; -} + } + /** + * For each entry in the TypeDoc JSON, remove it if: + * - it was not exported in index.ts + * - the constructor is to be ignored + * - it begins with an underscore (i.e is private) + */ + private _pruneTypedocOutput(typedocOutput: any): any { + const modifiedTypedocOutput = _.clone(typedocOutput); + _.each(typedocOutput.children, (file, i) => { + const exportPath = this._findExportPathGivenTypedocName(file.name); + const exportItems = this._exportPathToExportedItems[exportPath]; + _.each(file.children, (child, j) => { + const isNotExported = !_.includes(exportItems, child.name); + if (isNotExported) { + delete modifiedTypedocOutput.children[i].children[j]; + return; + } -function getAllReferenceNames(propertyName: string, node: any, referenceNames: string[]): string[] { - let updatedReferenceNames = referenceNames; - if (!_.isObject(node)) { - return updatedReferenceNames; + const innerChildren = typedocOutput.children[i].children[j].children; + _.each(innerChildren, (innerChild, k) => { + const isHiddenConstructor = + child.kindString === 'Class' && + _.includes(docGenConfigs.CLASSES_WITH_HIDDEN_CONSTRUCTORS, child.name) && + innerChild.kindString === 'Constructor'; + const isPrivate = _.startsWith(innerChild.name, '_'); + if (isHiddenConstructor || isPrivate) { + delete modifiedTypedocOutput.children[i].children[j].children[k]; + modifiedTypedocOutput.children[i].children[j].children = _.compact( + modifiedTypedocOutput.children[i].children[j].children, + ); + } + }); + }); + modifiedTypedocOutput.children[i].children = _.compact(modifiedTypedocOutput.children[i].children); + }); + return modifiedTypedocOutput; } - // Some nodes of type reference are for subtypes, which we don't want to return. - // We therefore filter them out. - const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites', 'extendedTypes']; - if ( - !_.isUndefined(node.type) && - _.isString(node.type) && - node.type === 'reference' && - _.isUndefined(node.typeArguments) && - !_.includes(SUB_TYPE_PROPERTY_NAMES, propertyName) - ) { - return [...referenceNames, node.name]; + /** + * Unfortunately TypeDoc children names will only be prefixed with the name of the package _if_ we passed + * TypeDoc files outside of the packages root path (i.e this package exports another package from our + * monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add + * them here when necessary. + */ + private _standardizeTypedocOutputTopLevelChildNames(typedocOutput: any): any { + const modifiedTypedocOutput = _.clone(typedocOutput); + _.each(typedocOutput.children, (child, i) => { + if (!_.includes(child.name, '/src/')) { + const nameWithoutQuotes = child.name.replace(/"/g, ''); + const standardizedName = `"${this._packageName}/src/${nameWithoutQuotes}"`; + modifiedTypedocOutput.children[i].name = standardizedName; + } + }); + return modifiedTypedocOutput; } - _.each(node, (nodeValue, innerPropertyName) => { - if (_.isArray(nodeValue)) { - _.each(nodeValue, aNode => { - updatedReferenceNames = getAllReferenceNames(innerPropertyName, aNode, updatedReferenceNames); - }); - } else if (_.isObject(nodeValue)) { - updatedReferenceNames = getAllReferenceNames(innerPropertyName, nodeValue, updatedReferenceNames); - } - }); - return updatedReferenceNames; -} - -function findExportPathGivenTypedocName( - exportPathToExportedItems: ExportPathToExportedItems, - packageName: string, - typedocName: string, -): string { - const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); - const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; - const exportPaths = _.keys(exportPathToExportedItems); - const sanitizedExportPaths = _.map(exportPaths, exportPath => { - if (_.startsWith(exportPath, './')) { - const sanitizedExportPath = path.join(packageName, 'src', exportPath); - sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; - return sanitizedExportPath; - } - const monorepoPrefix = '@0xproject/'; - if (_.startsWith(exportPath, monorepoPrefix)) { - const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; - sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; - return sanitizedExportPath; + /** + * Maps back each top-level TypeDoc JSON object name to the exportPath from which it was generated. + */ + private _findExportPathGivenTypedocName(typedocName: string): string { + const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); + const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; + const exportPaths = _.keys(this._exportPathToExportedItems); + const sanitizedExportPaths = _.map(exportPaths, exportPath => { + if (_.startsWith(exportPath, './')) { + const sanitizedExportPath = path.join(this._packageName, 'src', exportPath); + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + const monorepoPrefix = '@0xproject/'; + if (_.startsWith(exportPath, monorepoPrefix)) { + const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; + sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; + return sanitizedExportPath; + } + sanitizedExportPathToExportPath[exportPath] = exportPath; + return exportPath; + }); + // We need to sort the exportPaths by length (longest first), so that the match finding will pick + // longer matches before shorter matches, since it might match both, but the longer match is more + // precisely what we are looking for. + const sanitizedExportPathsSortedByLength = sanitizedExportPaths.sort((a: string, b: string) => { + return b.length - a.length; + }); + const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPathsSortedByLength, p => { + return _.startsWith(typeDocNameWithoutQuotes, p); + }); + if (_.isUndefined(matchingSanitizedExportPathIfExists)) { + throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); } - sanitizedExportPathToExportPath[exportPath] = exportPath; - return exportPath; - }); - // We need to sort the exportPaths by length (longest first), so that the match finding will pick - // longer matches before shorter matches, since it might match both, but the longer match is more - // precisely what we are looking for. - const sanitizedExportPathsSortedByLength = sanitizedExportPaths.sort((a: string, b: string) => { - return b.length - a.length; - }); - const matchingSanitizedExportPathIfExists = _.find(sanitizedExportPathsSortedByLength, p => { - return _.startsWith(typeDocNameWithoutQuotes, p); - }); - if (_.isUndefined(matchingSanitizedExportPathIfExists)) { - throw new Error(`Didn't find an exportPath for ${typeDocNameWithoutQuotes}`); + const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; + return matchingExportPath; } - const matchingExportPath = sanitizedExportPathToExportPath[matchingSanitizedExportPathIfExists]; - return matchingExportPath; -} - -function getExportPathToExportedItems(filePath: string, omitExports?: string[]): ExportInfo { - const sourceFile = ts.createSourceFile( - 'indexFile', - readFileSync(filePath).toString(), - ts.ScriptTarget.ES2017, - /*setParentNodes */ true, - ); - const exportInfo = _getExportPathToExportedItems(sourceFile, omitExports); - return exportInfo; -} - -function _getExportPathToExportedItems(sf: ts.SourceFile, omitExports?: string[]): ExportInfo { - const exportPathToExportedItems: ExportPathToExportedItems = {}; - const exportPathOrder: string[] = []; - const exportsToOmit = _.isUndefined(omitExports) ? [] : omitExports; - processNode(sf); - - function processNode(node: ts.Node): void { - switch (node.kind) { - case ts.SyntaxKind.ExportDeclaration: { - const exportClause = (node as any).exportClause; - const exportPath = exportClause.parent.moduleSpecifier.text; - _.each(exportClause.elements, element => { - const exportItem = element.name.escapedText; - if (!_.includes(exportsToOmit, exportItem)) { - exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) - ? [exportItem] - : [...exportPathToExportedItems[exportPath], exportItem]; - } + private _getAllExternalExports(): string[] { + const externalExports: string[] = []; + _.each(this._exportPathToExportedItems, (exportedItems, exportPath) => { + const pathIfExists = this._monoRepoPkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + _.each(exportedItems, exportedItem => { + externalExports.push(exportedItem); }); - if (!_.isUndefined(exportPathToExportedItems[exportPath])) { - exportPathOrder.push(exportPath); - } - break; + return; // It's an external package + } + }); + return externalExports; + } + private _getTypeDocFileIncludesForPackage(): string[] { + let typeDocExtraFileIncludes: string[] = []; + _.each(this._exportPathToExportedItems, (exportedItems, exportPath) => { + const isInternalToPkg = _.startsWith(exportPath, '.'); + if (isInternalToPkg) { + const pathToInternalPkg = path.join(this._packagePath, 'src', `${exportPath}.ts`); + typeDocExtraFileIncludes.push(pathToInternalPkg); + return; } - case ts.SyntaxKind.ExportKeyword: { - const foundNode: any = node; - let exportPath = './index'; - if (foundNode.parent && foundNode.parent.name) { - const exportItem = foundNode.parent.name.escapedText; - const isExportImportRequireStatement = !_.isUndefined( - _.get(foundNode, 'parent.moduleReference.expression.text'), - ); - if (isExportImportRequireStatement) { - exportPath = foundNode.parent.moduleReference.expression.text; + const pathIfExists = this._monoRepoPkgNameToPath[exportPath]; + if (_.isUndefined(pathIfExists)) { + return; // It's an external package + } + + const typeDocSourceIncludes = new Set(); + const pathToIndex = `${pathIfExists}/src/index.ts`; + const exportInfo = DocGenerateAndUploadUtils._getExportPathToExportedItems(pathToIndex); + const innerExportPathToExportedItems = exportInfo.exportPathToExportedItems; + _.each(exportedItems, exportName => { + _.each(innerExportPathToExportedItems, (innerExportItems, innerExportPath) => { + if (!_.includes(innerExportItems, exportName)) { + return; } - if (!_.includes(exportsToOmit, exportItem)) { - exportPathToExportedItems[exportPath] = _.isUndefined(exportPathToExportedItems[exportPath]) - ? [exportItem] - : [...exportPathToExportedItems[exportPath], exportItem]; + if (!_.startsWith(innerExportPath, './')) { + throw new Error( + `GENERATE_UPLOAD_DOCS: WARNING - ${ + this._packageName + } is exporting one of ${innerExportItems} which is + itself exported from an external package. To fix this, export the external dependency directly, + not indirectly through ${innerExportPath}.`, + ); + } else { + const absoluteSrcPath = path.join(pathIfExists, 'src', `${innerExportPath}.ts`); + typeDocSourceIncludes.add(absoluteSrcPath); } - } - if (!_.includes(exportPathOrder, exportPath) && !_.isUndefined(exportPathToExportedItems[exportPath])) { - exportPathOrder.push(exportPath); - } - break; + }); + }); + + // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types + // directly, meaning no internal paths will exist to follow. Other packages also have direct exports + // in their index.ts, so we always add it to the source files passed to TypeDoc + if (typeDocSourceIncludes.size === 0) { + typeDocSourceIncludes.add(pathToIndex); } - default: - // noop - break; - } - ts.forEachChild(node, processNode); + typeDocExtraFileIncludes = [...typeDocExtraFileIncludes, ...Array.from(typeDocSourceIncludes)]; + }); + return typeDocExtraFileIncludes; } - const exportInfo = { - exportPathToExportedItems, - exportPathOrder, - }; - return exportInfo; } -- cgit v1.2.3 From ea4d7f153aed24ca8ea136b6d0671c65462c915b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 17 Aug 2018 14:12:04 -0700 Subject: Also ignore implementationOf --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index a2902d1e4..ac4000461 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -54,7 +54,7 @@ export class DocGenerateAndUploadUtils { let updatedReferenceNames = referenceNames; // Some nodes of type reference are for subtypes, which we don't want to return. // We therefore filter them out. - const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites', 'extendedTypes']; + const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites', 'extendedTypes', 'implementationOf']; if ( !_.isUndefined(node.type) && _.isString(node.type) && -- cgit v1.2.3 From 0f7ced3625417f0de14d3158551971d1b558fa2e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 17 Aug 2018 14:12:23 -0700 Subject: Make sure export isn't internal to the package --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index ac4000461..c321aa823 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -411,7 +411,7 @@ export class DocGenerateAndUploadUtils { const externalExports: string[] = []; _.each(this._exportPathToExportedItems, (exportedItems, exportPath) => { const pathIfExists = this._monoRepoPkgNameToPath[exportPath]; - if (_.isUndefined(pathIfExists)) { + if (_.isUndefined(pathIfExists) && !_.startsWith(exportPath, './')) { _.each(exportedItems, exportedItem => { externalExports.push(exportedItem); }); -- cgit v1.2.3 From e7c7af8ef4ffb5dc3f1cbe468d272f4b9424fdc7 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 11:15:59 +0100 Subject: Add more types and ignores to docGenConfigs --- packages/monorepo-scripts/src/doc_gen_configs.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index fd95863c3..41142d9c8 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -11,10 +11,13 @@ export const docGenConfigs: DocGenConfigs = { 'solc.CompilerSettings': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#input-description', Schema: 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', + Uint8Array: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array', + 'Ganache.GanacheOpts': + 'https://github.com/0xProject/0x-monorepo/blob/ddf85112d7e4eb1581e0d82ce6eedad429641106/packages/typescript-typings/types/ganache-core/index.d.ts#L3', + 'lightwallet.keystore': + 'https://github.com/0xProject/0x-monorepo/blob/ddf85112d7e4eb1581e0d82ce6eedad429641106/packages/typescript-typings/types/eth-lightwallet/index.d.ts#L32', }, - /** - * If a 0x package re-exports an external package, we should add a link to it's exported items here - */ + // If a 0x package re-exports an external package, we should add a link to it's exported items here EXTERNAL_EXPORT_TO_LINK: { Web3ProviderEngine: 'https://www.npmjs.com/package/web3-provider-engine', BigNumber: 'https://www.npmjs.com/package/bignumber.js', @@ -30,4 +33,8 @@ export const docGenConfigs: DocGenConfigs = { 'ExchangeWrapper', 'ForwarderWrapper', ], + // Some types are not explicitly part of the public interface like params, return values, etc... But we still + // want them exported. E.g error enum types that can be thrown by methods. These must be manually added to this + // config + IGNORED_EXCESSIVE_TYPES: ['NonceSubproviderErrors', 'Web3WrapperErrors', 'ContractWrappersError', 'OrderError'], }; -- cgit v1.2.3 From 635373febb6e6d24a08549b2eb0db29a3d7619e6 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 11:17:12 +0100 Subject: Implement ignoring config types --- packages/monorepo-scripts/src/types.ts | 1 + .../monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index 5f6a6c707..9b6846f02 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -55,6 +55,7 @@ export interface DocGenConfigs { EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string }; EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string }; CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[]; + IGNORED_EXCESSIVE_TYPES: string[]; } export interface ExportPathToExportedItems { diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index c321aa823..e9586e68b 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -308,9 +308,13 @@ export class DocGenerateAndUploadUtils { private _lookForUnusedExportedTypesThrowIfExists(referenceNames: string[], typedocOutput: any): void { const exportedTypes = DocGenerateAndUploadUtils._getAllTypeNames(typedocOutput, []); const excessiveReferences = _.difference(exportedTypes, referenceNames); - if (!_.isEmpty(excessiveReferences)) { + const excessiveReferencesExceptIgnored = _.difference( + excessiveReferences, + docGenConfigs.IGNORED_EXCESSIVE_TYPES, + ); + if (!_.isEmpty(excessiveReferencesExceptIgnored)) { throw new Error( - `${this._packageName} package exports BUT does not need: \n${excessiveReferences.join( + `${this._packageName} package exports BUT does not need: \n${excessiveReferencesExceptIgnored.join( '\n', )} \nin it\'s index.ts. Remove them then try again.`, ); -- cgit v1.2.3 From 151cf03f5b697ee757ca3c2a44c5e59e3c2fe09c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 16:35:39 +0100 Subject: Add link to Array type --- packages/monorepo-scripts/src/doc_gen_configs.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 41142d9c8..83fae1e7c 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -3,6 +3,7 @@ import { DocGenConfigs } from './types'; export const docGenConfigs: DocGenConfigs = { DOC_JSON_VERSION: '0.0.1', EXTERNAL_TYPE_TO_LINK: { + Array: 'https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Array', BigNumber: 'http://mikemcl.github.io/bignumber.js', Error: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error', Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262', -- cgit v1.2.3 From c52c94214f9eb9ba25edc5e4599048663cd9cfa1 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 16:36:48 +0100 Subject: Rather then look for typeArguments, we want to ignore Partial & Promise references, but still continue to search below them, as they might surround a type --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index e9586e68b..adb898628 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -59,7 +59,8 @@ export class DocGenerateAndUploadUtils { !_.isUndefined(node.type) && _.isString(node.type) && node.type === 'reference' && - _.isUndefined(node.typeArguments) && + node.name !== 'Partial' && + node.name !== 'Promise' && !_.includes(SUB_TYPE_PROPERTY_NAMES, propertyName) ) { updatedReferenceNames = _.uniq([...referenceNames, node.name]); -- cgit v1.2.3 From a7468eb858bc730d4b7ca92260314cfa0c51416b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 17:16:00 +0100 Subject: Don't check if types are used for libraries only include types --- packages/monorepo-scripts/src/doc_gen_configs.ts | 3 +++ .../monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 83fae1e7c..52cbc4f59 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -38,4 +38,7 @@ export const docGenConfigs: DocGenConfigs = { // want them exported. E.g error enum types that can be thrown by methods. These must be manually added to this // config IGNORED_EXCESSIVE_TYPES: ['NonceSubproviderErrors', 'Web3WrapperErrors', 'ContractWrappersError', 'OrderError'], + // Some libraries only export types. In those cases, we cannot check if the exported types are part of the + // "exported public interface". Thus we add them here and skip those checks. + TYPES_ONLY_LIBRARIES: ['ethereum-types', 'types'], }; diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index adb898628..cc4d70d63 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -212,10 +212,16 @@ export class DocGenerateAndUploadUtils { let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput); modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput); + if (!_.includes(docGenConfigs.TYPES_ONLY_LIBRARIES, this._packageName)) { const propertyName = ''; // Root has no property name - const referenceNames = DocGenerateAndUploadUtils._getAllReferenceNames(propertyName, modifiedTypedocOutput, []); + const referenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( + propertyName, + modifiedTypedocOutput, + [], + ); this._lookForUnusedExportedTypesThrowIfExists(referenceNames, modifiedTypedocOutput); this._lookForMissingReferenceExportsThrowIfExists(referenceNames); + } // Some of our packages re-export external package exports in their index.ts // Typedoc is incapable of rendering these packages, so we need to special-case them -- cgit v1.2.3 From 1ddac0bc7b21971698a7b70f47fdfabde2335505 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 17:16:16 +0100 Subject: Fix type --- packages/monorepo-scripts/src/types.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index 9b6846f02..3c2ec5069 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -56,6 +56,7 @@ export interface DocGenConfigs { EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string }; CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[]; IGNORED_EXCESSIVE_TYPES: string[]; + TYPES_ONLY_LIBRARIES: string[]; } export interface ExportPathToExportedItems { -- cgit v1.2.3 From 8bb7b5b543c4d914067b6bbb269be9cc2ac7f647 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 18:49:56 +0100 Subject: Add shouldUpload flag to docGenAndUpload command --- packages/monorepo-scripts/src/doc_generate_and_upload.ts | 9 ++++++++- .../monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index 602247972..77dc2f323 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -13,12 +13,19 @@ const args = yargs type: 'boolean', demandOption: true, }) + .option('shouldUpload', { + describe: 'Whether we wish to upload the docs to S3 or not', + type: 'boolean', + demandOption: false, + default: true, + }) .example("$0 --package '0x.js' --isStaging true", 'Full usage example').argv; (async () => { const packageName = args.package; const isStaging = args.isStaging; + const shouldUploadDocs = args.shouldUpload; - const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageName, isStaging); + const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageName, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); })(); diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index cc4d70d63..7e8bd07da 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -12,6 +12,7 @@ import { utils } from './utils'; export class DocGenerateAndUploadUtils { private _isStaging: boolean; + private _shouldUploadDocs: boolean; private _packageName: string; private _omitExports: string[]; private _packagePath: string; @@ -155,9 +156,10 @@ export class DocGenerateAndUploadUtils { }; return exportInfo; } - constructor(packageName: string, isStaging: boolean) { + constructor(packageName: string, isStaging: boolean, shouldUploadDocs: boolean) { this._isStaging = isStaging; this._packageName = packageName; + this._shouldUploadDocs = shouldUploadDocs; this._packagePath = `${constants.monorepoRootPath}/packages/${packageName}`; this._monoRepoPkgNameToPath = {}; @@ -268,6 +270,11 @@ export class DocGenerateAndUploadUtils { }; writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); + if (this._shouldUploadDocs) { + await this._uploadDocsAsync(jsonFilePath, cwd); + } + } + private async _uploadDocsAsync(jsonFilePath: string, cwd: string) { const fileName = `v${this._packageJson.version}.json`; utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); -- cgit v1.2.3 From 6b838c034a3a489ae0b962af820270eafc52c377 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 19:07:20 +0100 Subject: Modify script so it can generate docs for a specific package or all packages with doc pages, add doc gen test to CircleCi runs --- packages/monorepo-scripts/src/doc_gen_configs.ts | 14 ++++ .../src/doc_generate_and_upload.ts | 9 +-- packages/monorepo-scripts/src/types.ts | 1 + .../src/utils/doc_generate_and_upload_utils.ts | 81 ++++++++++++---------- 4 files changed, 65 insertions(+), 40 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 52cbc4f59..a7314776e 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -2,6 +2,20 @@ import { DocGenConfigs } from './types'; export const docGenConfigs: DocGenConfigs = { DOC_JSON_VERSION: '0.0.1', + // Packages for which doc pages exist + PACKAGES_WITH_DOC_PAGES: [ + '0x.js', + 'connect', + 'json-schemas', + 'subproviders', + 'web3-wrapper', + 'contract-wrappers', + 'order-utils', + 'order-watcher', + 'sol-compiler', + 'sol-cov', + 'ethereum-types', + ]; EXTERNAL_TYPE_TO_LINK: { Array: 'https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Array', BigNumber: 'http://mikemcl.github.io/bignumber.js', diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index 77dc2f323..7b6f2d9f0 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -4,9 +4,10 @@ import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils const args = yargs .option('package', { - describe: 'Monorepo sub-package for which to generate DocJSON', + describe: + 'Monorepo sub-package for which to generate DocJSON. If not supplied, it will do all defined in docGenConfigs.', type: 'string', - demandOption: true, + demandOption: false, }) .option('isStaging', { describe: 'Whether we wish to publish docs to staging or production', @@ -22,10 +23,10 @@ const args = yargs .example("$0 --package '0x.js' --isStaging true", 'Full usage example').argv; (async () => { - const packageName = args.package; + const packageNameIfExists = args.package; const isStaging = args.isStaging; const shouldUploadDocs = args.shouldUpload; - const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageName, isStaging, shouldUploadDocs); + const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageNameIfExists, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); })(); diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index 3c2ec5069..b87cc47eb 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -52,6 +52,7 @@ export interface Package { export interface DocGenConfigs { DOC_JSON_VERSION: string; + PACKAGES_WITH_DOC_PAGES: string[]; EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string }; EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string }; CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[]; diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 7e8bd07da..c84413e64 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -13,7 +13,7 @@ import { utils } from './utils'; export class DocGenerateAndUploadUtils { private _isStaging: boolean; private _shouldUploadDocs: boolean; - private _packageName: string; + private _packageNameIfExists: string; private _omitExports: string[]; private _packagePath: string; private _exportPathToExportedItems: ExportPathToExportedItems; @@ -156,21 +156,21 @@ export class DocGenerateAndUploadUtils { }; return exportInfo; } - constructor(packageName: string, isStaging: boolean, shouldUploadDocs: boolean) { + constructor(packageNameIfExists: string, isStaging: boolean, shouldUploadDocs: boolean) { this._isStaging = isStaging; - this._packageName = packageName; + this._packageNameIfExists = packageNameIfExists; this._shouldUploadDocs = shouldUploadDocs; - this._packagePath = `${constants.monorepoRootPath}/packages/${packageName}`; + this._packagePath = `${constants.monorepoRootPath}/packages/${packageNameIfExists}`; this._monoRepoPkgNameToPath = {}; const monorepoPackages = utils.getPackages(constants.monorepoRootPath); _.each(monorepoPackages, p => (this._monoRepoPkgNameToPath[p.packageJson.name] = p.location)); const pkg = _.find(monorepoPackages, monorepoPackage => { - return _.includes(monorepoPackage.packageJson.name, packageName); + return _.includes(monorepoPackage.packageJson.name, packageNameIfExists); }); if (_.isUndefined(pkg)) { - throw new Error(`Couldn't find a package.json for ${packageName}`); + throw new Error(`Couldn't find a package.json for ${packageNameIfExists}`); } this._packageJson = pkg.packageJson; this._omitExports = _.get(this._packageJson, 'config.postpublish.omitExports', []); @@ -191,17 +191,26 @@ export class DocGenerateAndUploadUtils { } } public async generateAndUploadDocsAsync(): Promise { + if (!_.isUndefined(this._packageNameIfExists)) { + await this.generateAndUploadDocsForPackageAsync(this._packageNameIfExists); + } else { + for (const packageName of docGenConfigs.PACKAGES_WITH_DOC_PAGES) { + await this.generateAndUploadDocsForPackageAsync(packageName); + } + } + } + private async generateAndUploadDocsForPackageAsync(packageName: string): Promise { // For each dep that is another one of our monorepo packages, we fetch it's index.ts // and see which specific files we must pass to TypeDoc, in order to generate a Doc JSON // the includes everything exported by the public interface. - const typeDocExtraFileIncludes: string[] = this._getTypeDocFileIncludesForPackage(); + const typeDocExtraFileIncludes: string[] = this._getTypeDocFileIncludesForPackage(packageName); // In order to avoid TS errors, we need to pass TypeDoc the package's global.d.ts file typeDocExtraFileIncludes.push(path.join(this._packagePath, 'src', 'globals.d.ts')); const jsonFilePath = path.join(this._packagePath, 'generated_docs', 'index.json'); const projectFiles = typeDocExtraFileIncludes.join(' '); - const cwd = path.join(constants.monorepoRootPath, 'packages', this._packageName); + const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the // packages root dir, does not work. It only works when called via a `package.json` script located // in the package's root. @@ -211,18 +220,18 @@ export class DocGenerateAndUploadUtils { const typedocOutputString = readFileSync(jsonFilePath).toString(); const typedocOutput = JSON.parse(typedocOutputString); - let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput); - modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput); + let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput, packageName); + modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput, packageName); - if (!_.includes(docGenConfigs.TYPES_ONLY_LIBRARIES, this._packageName)) { - const propertyName = ''; // Root has no property name + if (!_.includes(docGenConfigs.TYPES_ONLY_LIBRARIES, packageName)) { + const propertyName = ''; // Root has no property name const referenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( propertyName, modifiedTypedocOutput, [], ); - this._lookForUnusedExportedTypesThrowIfExists(referenceNames, modifiedTypedocOutput); - this._lookForMissingReferenceExportsThrowIfExists(referenceNames); + this._lookForUnusedExportedTypesThrowIfExists(referenceNames, modifiedTypedocOutput, packageName); + this._lookForMissingReferenceExportsThrowIfExists(referenceNames, packageName); } // Some of our packages re-export external package exports in their index.ts @@ -240,9 +249,7 @@ export class DocGenerateAndUploadUtils { }); if (!_.isEmpty(externalExportsWithoutLinks)) { throw new Error( - `Found the following external exports in ${ - this._packageName - }'s index.ts:\n ${externalExportsWithoutLinks.join( + `Found the following external exports in ${packageName}'s index.ts:\n ${externalExportsWithoutLinks.join( '\n', )}\nThey are missing from the EXTERNAL_EXPORT_TO_LINK mapping. Add them and try again.`, ); @@ -250,7 +257,7 @@ export class DocGenerateAndUploadUtils { const exportPathToTypedocNames: ExportNameToTypedocNames = {}; _.each(modifiedTypedocOutput.children, file => { - const exportPath = this._findExportPathGivenTypedocName(file.name); + const exportPath = this._findExportPathGivenTypedocName(file.name, packageName); exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) ? [file.name] : [...exportPathToTypedocNames[exportPath], file.name]; @@ -271,16 +278,16 @@ export class DocGenerateAndUploadUtils { writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); if (this._shouldUploadDocs) { - await this._uploadDocsAsync(jsonFilePath, cwd); + await this._uploadDocsAsync(jsonFilePath, cwd, packageName); } } - private async _uploadDocsAsync(jsonFilePath: string, cwd: string) { + private async _uploadDocsAsync(jsonFilePath: string, cwd: string, packageName: string) { const fileName = `v${this._packageJson.version}.json`; utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); const S3BucketPath = this._isStaging - ? `s3://staging-doc-jsons/${this._packageName}/` - : `s3://doc-jsons/${this._packageName}/`; + ? `s3://staging-doc-jsons/${packageName}/` + : `s3://doc-jsons/${packageName}/`; const s3Url = `${S3BucketPath}${fileName}`; await execAsync( `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, @@ -297,7 +304,7 @@ export class DocGenerateAndUploadUtils { /** * Look for types that are used by the public interface but are missing from a package's index.ts */ - private _lookForMissingReferenceExportsThrowIfExists(referenceNames: string[]): void { + private _lookForMissingReferenceExportsThrowIfExists(referenceNames: string[], packageName: string): void { const allExportedItems = _.flatten(_.values(this._exportPathToExportedItems)); const missingReferences: string[] = []; _.each(referenceNames, referenceName => { @@ -310,7 +317,7 @@ export class DocGenerateAndUploadUtils { }); if (!_.isEmpty(missingReferences)) { throw new Error( - `${this._packageName} package needs to export: \n${missingReferences.join( + `${packageName} package needs to export: \n${missingReferences.join( '\n', )} \nFrom it\'s index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, ); @@ -319,7 +326,11 @@ export class DocGenerateAndUploadUtils { /** * Look for exported types that are not used by the package's public interface */ - private _lookForUnusedExportedTypesThrowIfExists(referenceNames: string[], typedocOutput: any): void { + private _lookForUnusedExportedTypesThrowIfExists( + referenceNames: string[], + typedocOutput: any, + packageName: string, + ): void { const exportedTypes = DocGenerateAndUploadUtils._getAllTypeNames(typedocOutput, []); const excessiveReferences = _.difference(exportedTypes, referenceNames); const excessiveReferencesExceptIgnored = _.difference( @@ -328,7 +339,7 @@ export class DocGenerateAndUploadUtils { ); if (!_.isEmpty(excessiveReferencesExceptIgnored)) { throw new Error( - `${this._packageName} package exports BUT does not need: \n${excessiveReferencesExceptIgnored.join( + `${packageName} package exports BUT does not need: \n${excessiveReferencesExceptIgnored.join( '\n', )} \nin it\'s index.ts. Remove them then try again.`, ); @@ -340,10 +351,10 @@ export class DocGenerateAndUploadUtils { * - the constructor is to be ignored * - it begins with an underscore (i.e is private) */ - private _pruneTypedocOutput(typedocOutput: any): any { + private _pruneTypedocOutput(typedocOutput: any, packageName: string): any { const modifiedTypedocOutput = _.clone(typedocOutput); _.each(typedocOutput.children, (file, i) => { - const exportPath = this._findExportPathGivenTypedocName(file.name); + const exportPath = this._findExportPathGivenTypedocName(file.name, packageName); const exportItems = this._exportPathToExportedItems[exportPath]; _.each(file.children, (child, j) => { const isNotExported = !_.includes(exportItems, child.name); @@ -377,12 +388,12 @@ export class DocGenerateAndUploadUtils { * monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add * them here when necessary. */ - private _standardizeTypedocOutputTopLevelChildNames(typedocOutput: any): any { + private _standardizeTypedocOutputTopLevelChildNames(typedocOutput: any, packageName: string): any { const modifiedTypedocOutput = _.clone(typedocOutput); _.each(typedocOutput.children, (child, i) => { if (!_.includes(child.name, '/src/')) { const nameWithoutQuotes = child.name.replace(/"/g, ''); - const standardizedName = `"${this._packageName}/src/${nameWithoutQuotes}"`; + const standardizedName = `"${packageName}/src/${nameWithoutQuotes}"`; modifiedTypedocOutput.children[i].name = standardizedName; } }); @@ -391,13 +402,13 @@ export class DocGenerateAndUploadUtils { /** * Maps back each top-level TypeDoc JSON object name to the exportPath from which it was generated. */ - private _findExportPathGivenTypedocName(typedocName: string): string { + private _findExportPathGivenTypedocName(typedocName: string, packageName: string): string { const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; const exportPaths = _.keys(this._exportPathToExportedItems); const sanitizedExportPaths = _.map(exportPaths, exportPath => { if (_.startsWith(exportPath, './')) { - const sanitizedExportPath = path.join(this._packageName, 'src', exportPath); + const sanitizedExportPath = path.join(packageName, 'src', exportPath); sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; return sanitizedExportPath; } @@ -438,7 +449,7 @@ export class DocGenerateAndUploadUtils { }); return externalExports; } - private _getTypeDocFileIncludesForPackage(): string[] { + private _getTypeDocFileIncludesForPackage(packageName: string): string[] { let typeDocExtraFileIncludes: string[] = []; _.each(this._exportPathToExportedItems, (exportedItems, exportPath) => { const isInternalToPkg = _.startsWith(exportPath, '.'); @@ -464,9 +475,7 @@ export class DocGenerateAndUploadUtils { } if (!_.startsWith(innerExportPath, './')) { throw new Error( - `GENERATE_UPLOAD_DOCS: WARNING - ${ - this._packageName - } is exporting one of ${innerExportItems} which is + `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is itself exported from an external package. To fix this, export the external dependency directly, not indirectly through ${innerExportPath}.`, ); -- cgit v1.2.3 From fe43f84abdeb2ed6805d3879f531fbc4f46c4fec Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 23:06:21 +0100 Subject: Use bash for loop for generating docs for each package, revert changes to script --- packages/monorepo-scripts/src/doc_gen_configs.ts | 14 ---- .../src/doc_generate_and_upload.ts | 15 ++-- packages/monorepo-scripts/src/publish.ts | 3 +- packages/monorepo-scripts/src/types.ts | 1 - .../src/utils/doc_generate_and_upload_utils.ts | 83 ++++++++++------------ 5 files changed, 51 insertions(+), 65 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index a7314776e..52cbc4f59 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -2,20 +2,6 @@ import { DocGenConfigs } from './types'; export const docGenConfigs: DocGenConfigs = { DOC_JSON_VERSION: '0.0.1', - // Packages for which doc pages exist - PACKAGES_WITH_DOC_PAGES: [ - '0x.js', - 'connect', - 'json-schemas', - 'subproviders', - 'web3-wrapper', - 'contract-wrappers', - 'order-utils', - 'order-watcher', - 'sol-compiler', - 'sol-cov', - 'ethereum-types', - ]; EXTERNAL_TYPE_TO_LINK: { Array: 'https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Array', BigNumber: 'http://mikemcl.github.io/bignumber.js', diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index 7b6f2d9f0..2a53628b5 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -5,9 +5,9 @@ import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils const args = yargs .option('package', { describe: - 'Monorepo sub-package for which to generate DocJSON. If not supplied, it will do all defined in docGenConfigs.', + 'Monorepo sub-package for which to generate DocJSON', type: 'string', - demandOption: false, + demandOption: true, }) .option('isStaging', { describe: 'Whether we wish to publish docs to staging or production', @@ -23,10 +23,15 @@ const args = yargs .example("$0 --package '0x.js' --isStaging true", 'Full usage example').argv; (async () => { - const packageNameIfExists = args.package; + const packageName = args.package; const isStaging = args.isStaging; const shouldUploadDocs = args.shouldUpload; - const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageNameIfExists, isStaging, shouldUploadDocs); + const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(packageName, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); -})(); + + process.exit(0); +})().catch(err => { + console.log(err); + process.exit(1); +}); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 6691fd3c1..7e91b9281 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -85,7 +85,8 @@ async function generateAndUploadDocJsonsAsync(updatedPublicPackages: Package[], for (const pkg of updatedPublicPackages) { const packageName = pkg.packageJson.name; const nameWithoutPrefix = packageName.replace('@0xproject/', ''); - const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging); + const shouldUploadDocs = true; + const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); } } diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index b87cc47eb..3c2ec5069 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -52,7 +52,6 @@ export interface Package { export interface DocGenConfigs { DOC_JSON_VERSION: string; - PACKAGES_WITH_DOC_PAGES: string[]; EXTERNAL_TYPE_TO_LINK: { [externalType: string]: string }; EXTERNAL_EXPORT_TO_LINK: { [externalExport: string]: string }; CLASSES_WITH_HIDDEN_CONSTRUCTORS: string[]; diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index c84413e64..9e5f437fa 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -13,7 +13,7 @@ import { utils } from './utils'; export class DocGenerateAndUploadUtils { private _isStaging: boolean; private _shouldUploadDocs: boolean; - private _packageNameIfExists: string; + private _packageName: string; private _omitExports: string[]; private _packagePath: string; private _exportPathToExportedItems: ExportPathToExportedItems; @@ -156,21 +156,21 @@ export class DocGenerateAndUploadUtils { }; return exportInfo; } - constructor(packageNameIfExists: string, isStaging: boolean, shouldUploadDocs: boolean) { + constructor(packageName: string, isStaging: boolean, shouldUploadDocs: boolean) { this._isStaging = isStaging; - this._packageNameIfExists = packageNameIfExists; + this._packageName = packageName; this._shouldUploadDocs = shouldUploadDocs; - this._packagePath = `${constants.monorepoRootPath}/packages/${packageNameIfExists}`; + this._packagePath = `${constants.monorepoRootPath}/packages/${packageName}`; this._monoRepoPkgNameToPath = {}; const monorepoPackages = utils.getPackages(constants.monorepoRootPath); _.each(monorepoPackages, p => (this._monoRepoPkgNameToPath[p.packageJson.name] = p.location)); const pkg = _.find(monorepoPackages, monorepoPackage => { - return _.includes(monorepoPackage.packageJson.name, packageNameIfExists); + return _.includes(monorepoPackage.packageJson.name, packageName); }); if (_.isUndefined(pkg)) { - throw new Error(`Couldn't find a package.json for ${packageNameIfExists}`); + throw new Error(`Couldn't find a package.json for ${packageName}`); } this._packageJson = pkg.packageJson; this._omitExports = _.get(this._packageJson, 'config.postpublish.omitExports', []); @@ -191,26 +191,18 @@ export class DocGenerateAndUploadUtils { } } public async generateAndUploadDocsAsync(): Promise { - if (!_.isUndefined(this._packageNameIfExists)) { - await this.generateAndUploadDocsForPackageAsync(this._packageNameIfExists); - } else { - for (const packageName of docGenConfigs.PACKAGES_WITH_DOC_PAGES) { - await this.generateAndUploadDocsForPackageAsync(packageName); - } - } - } - private async generateAndUploadDocsForPackageAsync(packageName: string): Promise { // For each dep that is another one of our monorepo packages, we fetch it's index.ts // and see which specific files we must pass to TypeDoc, in order to generate a Doc JSON // the includes everything exported by the public interface. - const typeDocExtraFileIncludes: string[] = this._getTypeDocFileIncludesForPackage(packageName); + const typeDocExtraFileIncludes: string[] = this._getTypeDocFileIncludesForPackage(); // In order to avoid TS errors, we need to pass TypeDoc the package's global.d.ts file typeDocExtraFileIncludes.push(path.join(this._packagePath, 'src', 'globals.d.ts')); + utils.log(`GENERATE_UPLOAD_DOCS: Generating Typedoc JSON for ${this._packageName}...`); const jsonFilePath = path.join(this._packagePath, 'generated_docs', 'index.json'); const projectFiles = typeDocExtraFileIncludes.join(' '); - const cwd = path.join(constants.monorepoRootPath, 'packages', packageName); + const cwd = path.join(constants.monorepoRootPath, 'packages', this._packageName); // HACK: For some reason calling `typedoc` command directly from here, even with `cwd` set to the // packages root dir, does not work. It only works when called via a `package.json` script located // in the package's root. @@ -218,20 +210,21 @@ export class DocGenerateAndUploadUtils { cwd, }); + utils.log('GENERATE_UPLOAD_DOCS: Modifying Typedoc JSON to our custom format...'); const typedocOutputString = readFileSync(jsonFilePath).toString(); const typedocOutput = JSON.parse(typedocOutputString); - let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput, packageName); - modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput, packageName); + let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput); + modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput); - if (!_.includes(docGenConfigs.TYPES_ONLY_LIBRARIES, packageName)) { + if (!_.includes(docGenConfigs.TYPES_ONLY_LIBRARIES, this._packageName)) { const propertyName = ''; // Root has no property name const referenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( propertyName, modifiedTypedocOutput, [], ); - this._lookForUnusedExportedTypesThrowIfExists(referenceNames, modifiedTypedocOutput, packageName); - this._lookForMissingReferenceExportsThrowIfExists(referenceNames, packageName); + this._lookForUnusedExportedTypesThrowIfExists(referenceNames, modifiedTypedocOutput); + this._lookForMissingReferenceExportsThrowIfExists(referenceNames); } // Some of our packages re-export external package exports in their index.ts @@ -249,7 +242,9 @@ export class DocGenerateAndUploadUtils { }); if (!_.isEmpty(externalExportsWithoutLinks)) { throw new Error( - `Found the following external exports in ${packageName}'s index.ts:\n ${externalExportsWithoutLinks.join( + `Found the following external exports in ${ + this._packageName + }'s index.ts:\n ${externalExportsWithoutLinks.join( '\n', )}\nThey are missing from the EXTERNAL_EXPORT_TO_LINK mapping. Add them and try again.`, ); @@ -257,7 +252,7 @@ export class DocGenerateAndUploadUtils { const exportPathToTypedocNames: ExportNameToTypedocNames = {}; _.each(modifiedTypedocOutput.children, file => { - const exportPath = this._findExportPathGivenTypedocName(file.name, packageName); + const exportPath = this._findExportPathGivenTypedocName(file.name); exportPathToTypedocNames[exportPath] = _.isUndefined(exportPathToTypedocNames[exportPath]) ? [file.name] : [...exportPathToTypedocNames[exportPath], file.name]; @@ -275,19 +270,21 @@ export class DocGenerateAndUploadUtils { }, typedocJson: modifiedTypedocOutput, }; + utils.log(`GENERATE_UPLOAD_DOCS: Saving Doc JSON to: ${jsonFilePath}`); writeFileSync(jsonFilePath, JSON.stringify(docJson, null, 2)); if (this._shouldUploadDocs) { - await this._uploadDocsAsync(jsonFilePath, cwd, packageName); + await this._uploadDocsAsync(jsonFilePath, cwd); } + utils.log(`GENERATE_UPLOAD_DOCS: Doc generation done for ${this._packageName}`); } - private async _uploadDocsAsync(jsonFilePath: string, cwd: string, packageName: string) { + private async _uploadDocsAsync(jsonFilePath: string, cwd: string) { const fileName = `v${this._packageJson.version}.json`; utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); const S3BucketPath = this._isStaging - ? `s3://staging-doc-jsons/${packageName}/` - : `s3://doc-jsons/${packageName}/`; + ? `s3://staging-doc-jsons/${this._packageName}/` + : `s3://doc-jsons/${this._packageName}/`; const s3Url = `${S3BucketPath}${fileName}`; await execAsync( `aws s3 cp ${jsonFilePath} ${s3Url} --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json`, @@ -304,7 +301,7 @@ export class DocGenerateAndUploadUtils { /** * Look for types that are used by the public interface but are missing from a package's index.ts */ - private _lookForMissingReferenceExportsThrowIfExists(referenceNames: string[], packageName: string): void { + private _lookForMissingReferenceExportsThrowIfExists(referenceNames: string[]): void { const allExportedItems = _.flatten(_.values(this._exportPathToExportedItems)); const missingReferences: string[] = []; _.each(referenceNames, referenceName => { @@ -317,7 +314,7 @@ export class DocGenerateAndUploadUtils { }); if (!_.isEmpty(missingReferences)) { throw new Error( - `${packageName} package needs to export: \n${missingReferences.join( + `${this._packageName} package needs to export: \n${missingReferences.join( '\n', )} \nFrom it\'s index.ts. If any are from external dependencies, then add them to the EXTERNAL_TYPE_TO_LINK mapping.`, ); @@ -326,11 +323,7 @@ export class DocGenerateAndUploadUtils { /** * Look for exported types that are not used by the package's public interface */ - private _lookForUnusedExportedTypesThrowIfExists( - referenceNames: string[], - typedocOutput: any, - packageName: string, - ): void { + private _lookForUnusedExportedTypesThrowIfExists(referenceNames: string[], typedocOutput: any): void { const exportedTypes = DocGenerateAndUploadUtils._getAllTypeNames(typedocOutput, []); const excessiveReferences = _.difference(exportedTypes, referenceNames); const excessiveReferencesExceptIgnored = _.difference( @@ -339,7 +332,7 @@ export class DocGenerateAndUploadUtils { ); if (!_.isEmpty(excessiveReferencesExceptIgnored)) { throw new Error( - `${packageName} package exports BUT does not need: \n${excessiveReferencesExceptIgnored.join( + `${this._packageName} package exports BUT does not need: \n${excessiveReferencesExceptIgnored.join( '\n', )} \nin it\'s index.ts. Remove them then try again.`, ); @@ -351,10 +344,10 @@ export class DocGenerateAndUploadUtils { * - the constructor is to be ignored * - it begins with an underscore (i.e is private) */ - private _pruneTypedocOutput(typedocOutput: any, packageName: string): any { + private _pruneTypedocOutput(typedocOutput: any): any { const modifiedTypedocOutput = _.clone(typedocOutput); _.each(typedocOutput.children, (file, i) => { - const exportPath = this._findExportPathGivenTypedocName(file.name, packageName); + const exportPath = this._findExportPathGivenTypedocName(file.name); const exportItems = this._exportPathToExportedItems[exportPath]; _.each(file.children, (child, j) => { const isNotExported = !_.includes(exportItems, child.name); @@ -388,12 +381,12 @@ export class DocGenerateAndUploadUtils { * monorepo). In order to enforce that the names are always prefixed with the package's name, we check and add * them here when necessary. */ - private _standardizeTypedocOutputTopLevelChildNames(typedocOutput: any, packageName: string): any { + private _standardizeTypedocOutputTopLevelChildNames(typedocOutput: any): any { const modifiedTypedocOutput = _.clone(typedocOutput); _.each(typedocOutput.children, (child, i) => { if (!_.includes(child.name, '/src/')) { const nameWithoutQuotes = child.name.replace(/"/g, ''); - const standardizedName = `"${packageName}/src/${nameWithoutQuotes}"`; + const standardizedName = `"${this._packageName}/src/${nameWithoutQuotes}"`; modifiedTypedocOutput.children[i].name = standardizedName; } }); @@ -402,13 +395,13 @@ export class DocGenerateAndUploadUtils { /** * Maps back each top-level TypeDoc JSON object name to the exportPath from which it was generated. */ - private _findExportPathGivenTypedocName(typedocName: string, packageName: string): string { + private _findExportPathGivenTypedocName(typedocName: string): string { const typeDocNameWithoutQuotes = _.replace(typedocName, /"/g, ''); const sanitizedExportPathToExportPath: { [sanitizedName: string]: string } = {}; const exportPaths = _.keys(this._exportPathToExportedItems); const sanitizedExportPaths = _.map(exportPaths, exportPath => { if (_.startsWith(exportPath, './')) { - const sanitizedExportPath = path.join(packageName, 'src', exportPath); + const sanitizedExportPath = path.join(this._packageName, 'src', exportPath); sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; return sanitizedExportPath; } @@ -449,7 +442,7 @@ export class DocGenerateAndUploadUtils { }); return externalExports; } - private _getTypeDocFileIncludesForPackage(packageName: string): string[] { + private _getTypeDocFileIncludesForPackage(): string[] { let typeDocExtraFileIncludes: string[] = []; _.each(this._exportPathToExportedItems, (exportedItems, exportPath) => { const isInternalToPkg = _.startsWith(exportPath, '.'); @@ -475,7 +468,9 @@ export class DocGenerateAndUploadUtils { } if (!_.startsWith(innerExportPath, './')) { throw new Error( - `GENERATE_UPLOAD_DOCS: WARNING - ${packageName} is exporting one of ${innerExportItems} which is + `GENERATE_UPLOAD_DOCS: WARNING - ${ + this._packageName + } is exporting one of ${innerExportItems} which is itself exported from an external package. To fix this, export the external dependency directly, not indirectly through ${innerExportPath}.`, ); -- cgit v1.2.3 From da15df2c2dd6de236f4ce4021e7be376547bef13 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Aug 2018 23:07:12 +0100 Subject: Stop logging to console for each packages without a package.json --- packages/monorepo-scripts/src/utils/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 26ac801bd..2ce36942c 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -48,7 +48,7 @@ export const utils = { }; packages.push(pkg); } catch (err) { - utils.log(`Couldn't find a 'package.json' for ${subpackageName}. Skipping.`); + // Couldn't find a 'package.json' for package. Skipping. } } } -- cgit v1.2.3 From c12f0d04bb2f0d5ad73943d02a592a110423a423 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 11:30:24 +0100 Subject: Fix bugs in doc gen due to clone vs cloneDeep and pre-maturely removing placeholder undefined's in array iteration --- .../src/utils/doc_generate_and_upload_utils.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 9e5f437fa..bbc763a6b 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -213,8 +213,8 @@ export class DocGenerateAndUploadUtils { utils.log('GENERATE_UPLOAD_DOCS: Modifying Typedoc JSON to our custom format...'); const typedocOutputString = readFileSync(jsonFilePath).toString(); const typedocOutput = JSON.parse(typedocOutputString); - let modifiedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput); - modifiedTypedocOutput = this._pruneTypedocOutput(modifiedTypedocOutput); + const standardizedTypedocOutput = this._standardizeTypedocOutputTopLevelChildNames(typedocOutput); + const modifiedTypedocOutput = this._pruneTypedocOutput(standardizedTypedocOutput); if (!_.includes(docGenConfigs.TYPES_ONLY_LIBRARIES, this._packageName)) { const propertyName = ''; // Root has no property name @@ -345,7 +345,7 @@ export class DocGenerateAndUploadUtils { * - it begins with an underscore (i.e is private) */ private _pruneTypedocOutput(typedocOutput: any): any { - const modifiedTypedocOutput = _.clone(typedocOutput); + const modifiedTypedocOutput = _.cloneDeep(typedocOutput); _.each(typedocOutput.children, (file, i) => { const exportPath = this._findExportPathGivenTypedocName(file.name); const exportItems = this._exportPathToExportedItems[exportPath]; @@ -365,11 +365,11 @@ export class DocGenerateAndUploadUtils { const isPrivate = _.startsWith(innerChild.name, '_'); if (isHiddenConstructor || isPrivate) { delete modifiedTypedocOutput.children[i].children[j].children[k]; - modifiedTypedocOutput.children[i].children[j].children = _.compact( - modifiedTypedocOutput.children[i].children[j].children, - ); } }); + modifiedTypedocOutput.children[i].children[j].children = _.compact( + modifiedTypedocOutput.children[i].children[j].children, + ); }); modifiedTypedocOutput.children[i].children = _.compact(modifiedTypedocOutput.children[i].children); }); @@ -382,7 +382,7 @@ export class DocGenerateAndUploadUtils { * them here when necessary. */ private _standardizeTypedocOutputTopLevelChildNames(typedocOutput: any): any { - const modifiedTypedocOutput = _.clone(typedocOutput); + const modifiedTypedocOutput = _.cloneDeep(typedocOutput); _.each(typedocOutput.children, (child, i) => { if (!_.includes(child.name, '/src/')) { const nameWithoutQuotes = child.name.replace(/"/g, ''); -- cgit v1.2.3 From d907b403788576c7d4fe51090a561f1e951126e2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 13:12:42 +0100 Subject: Fix remaining merge issues --- packages/monorepo-scripts/src/doc_gen_configs.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 52cbc4f59..fb6cc0886 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -33,6 +33,7 @@ export const docGenConfigs: DocGenConfigs = { 'EtherTokenWrapper', 'ExchangeWrapper', 'ForwarderWrapper', + 'TransactionEncoder', ], // Some types are not explicitly part of the public interface like params, return values, etc... But we still // want them exported. E.g error enum types that can be thrown by methods. These must be manually added to this -- cgit v1.2.3 From 392c00a698ff774c13bcd63f458df3cea478cf99 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 15:10:32 +0100 Subject: Fix prettier --- packages/monorepo-scripts/src/doc_generate_and_upload.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index 2a53628b5..c70ea5ba7 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -4,8 +4,7 @@ import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils const args = yargs .option('package', { - describe: - 'Monorepo sub-package for which to generate DocJSON', + describe: 'Monorepo sub-package for which to generate DocJSON', type: 'string', demandOption: true, }) -- cgit v1.2.3 From b7c119b2aaaa2f3579ca4aeef198eca7f38f1216 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 18:52:17 +0100 Subject: Fix many linter errors that showed up upon upgrading tsutil --- packages/monorepo-scripts/package.json | 4 +++- .../monorepo-scripts/src/doc_generate_and_upload.ts | 3 ++- .../monorepo-scripts/src/publish_release_notes.ts | 6 ++---- .../src/utils/doc_generate_and_upload_utils.ts | 20 ++++++++++---------- .../src/utils/github_release_utils.ts | 18 ++++++++++-------- 5 files changed, 27 insertions(+), 24 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 41a6e7c91..74be99550 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -38,6 +38,7 @@ "@types/opn": "^5.1.0", "@types/rimraf": "^2.0.2", "@types/semver": "5.5.0", + "@types/yargs": "^10.0.0", "depcheck": "^0.6.9", "make-promises-safe": "^1.1.0", "npm-run-all": "^4.1.2", @@ -64,7 +65,8 @@ "semver": "5.5.0", "semver-diff": "^2.1.0", "semver-sort": "0.0.4", - "typedoc": "0xProject/typedoc" + "typedoc": "0xProject/typedoc", + "yargs": "^10.0.3" }, "publishConfig": { "access": "public" diff --git a/packages/monorepo-scripts/src/doc_generate_and_upload.ts b/packages/monorepo-scripts/src/doc_generate_and_upload.ts index c70ea5ba7..4c4a72701 100644 --- a/packages/monorepo-scripts/src/doc_generate_and_upload.ts +++ b/packages/monorepo-scripts/src/doc_generate_and_upload.ts @@ -1,6 +1,7 @@ import * as yargs from 'yargs'; import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils'; +import { utils } from './utils/utils'; const args = yargs .option('package', { @@ -31,6 +32,6 @@ const args = yargs process.exit(0); })().catch(err => { - console.log(err); + utils.log(err); process.exit(1); }); diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 964f5b0bb..5afcc8775 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -1,9 +1,7 @@ -import * as promisify from 'es6-promisify'; -import * as publishRelease from 'publish-release'; - -import { utils } from './utils/utils'; import { publishReleaseNotesAsync } from './utils/github_release_utils'; +import { utils } from './utils/utils'; +// tslint:disable-next-line:no-floating-promises (async () => { const shouldIncludePrivate = false; const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index bbc763a6b..1645ba0d6 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -11,15 +11,15 @@ import { ExportInfo, ExportNameToTypedocNames, ExportPathToExportedItems, Packag import { utils } from './utils'; export class DocGenerateAndUploadUtils { - private _isStaging: boolean; - private _shouldUploadDocs: boolean; - private _packageName: string; - private _omitExports: string[]; - private _packagePath: string; - private _exportPathToExportedItems: ExportPathToExportedItems; - private _exportPathOrder: string[]; - private _monoRepoPkgNameToPath: { [name: string]: string }; - private _packageJson: PackageJSON; + private readonly _isStaging: boolean; + private readonly _shouldUploadDocs: boolean; + private readonly _packageName: string; + private readonly _omitExports: string[]; + private readonly _packagePath: string; + private readonly _exportPathToExportedItems: ExportPathToExportedItems; + private readonly _exportPathOrder: string[]; + private readonly _monoRepoPkgNameToPath: { [name: string]: string }; + private readonly _packageJson: PackageJSON; /** * Recursively iterate over the TypeDoc JSON object and find all type names */ @@ -278,7 +278,7 @@ export class DocGenerateAndUploadUtils { } utils.log(`GENERATE_UPLOAD_DOCS: Doc generation done for ${this._packageName}`); } - private async _uploadDocsAsync(jsonFilePath: string, cwd: string) { + private async _uploadDocsAsync(jsonFilePath: string, cwd: string): Promise { const fileName = `v${this._packageJson.version}.json`; utils.log(`GENERATE_UPLOAD_DOCS: Doc generation successful, uploading docs... as ${fileName}`); diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 1f4c4f1e9..28dce70ac 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -1,27 +1,29 @@ -import * as _ from 'lodash'; import * as promisify from 'es6-promisify'; +import { readFileSync } from 'fs'; +import * as _ from 'lodash'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; import * as publishRelease from 'publish-release'; import { constants } from '../constants'; import { Package } from '../types'; -import { utils } from './utils'; -import { readFileSync } from 'fs'; -import * as path from 'path'; -import { exec as execAsync } from 'promisify-child-process'; +import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); +// tslint:disable-next-line:completed-docs export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); const latestGitCommit = result.stdout; - const shortenedGitCommit = latestGitCommit.slice(0, 7); + const prefixLength = 7; + const shortenedGitCommit = latestGitCommit.slice(0, prefixLength); const tagName = `monorepo@${shortenedGitCommit}`; await execAsync(`git rev-parse ${tagName}`); - await execAsync('git tag ${tagName}'); + await execAsync(`git tag ${tagName}`); - await execAsync('git push origin ${tagName}'); + await execAsync(`git push origin ${tagName}`); const releaseName = `0x monorepo - ${shortenedGitCommit}`; let assets: string[] = []; -- cgit v1.2.3 From 69b436babee4959a0bb6b5c78e3ea26e2a2f9720 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 23:13:59 +0100 Subject: Refactor publish script so that root package.json configs.packagesWithDocs is canonical source of which packages have doc pages --- packages/monorepo-scripts/src/publish.ts | 53 ++++++++++++---------- .../src/utils/doc_generate_and_upload_utils.ts | 12 +---- 2 files changed, 30 insertions(+), 35 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 7e91b9281..3b5070395 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node import * as promisify from 'es6-promisify'; +import * as fs from 'fs'; import * as _ from 'lodash'; import * as moment from 'moment'; import opn = require('opn'); @@ -35,12 +36,13 @@ async function confirmAsync(message: string): Promise { // Fetch public, updated Lerna packages const shouldIncludePrivate = true; const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + const packagesWithDocs = getPackagesWithDocs(allUpdatedPackages); 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); + await confirmDocPagesRenderAsync(packagesWithDocs); } // Update CHANGELOGs @@ -74,57 +76,60 @@ async function confirmAsync(message: string): Promise { utils.log(`Calling 'lerna publish'...`); await lernaPublishAsync(packageToNextVersion); const isStaging = false; - await generateAndUploadDocJsonsAsync(updatedPublicPackages, isStaging); + await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging); await publishReleaseNotesAsync(updatedPublicPackages); })().catch(err => { utils.log(err); process.exit(1); }); -async function generateAndUploadDocJsonsAsync(updatedPublicPackages: Package[], isStaging: boolean): Promise { - for (const pkg of updatedPublicPackages) { - const packageName = pkg.packageJson.name; - const nameWithoutPrefix = packageName.replace('@0xproject/', ''); +function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] { + const rootPackageJsonPath = `${constants.monorepoRootPath}/package.json`; + const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath).toString()); + const packagesWithDocPagesStringIfExist = _.get(rootPackageJson, 'configs.packagesWithDocPages', undefined); + if (_.isUndefined(packagesWithDocPagesStringIfExist)) { + return []; // None to generate & publish + } + const packagesWithDocPages = packagesWithDocPagesStringIfExist.split(' '); + const updatedPackagesWithDocPages: Package[] = []; + _.each(allUpdatedPackages, pkg => { + const nameWithoutPrefix = pkg.packageJson.name.replace('@0xproject/', ''); + if (_.includes(packagesWithDocPages, nameWithoutPrefix)) { + updatedPackagesWithDocPages.push(pkg); + } + }); + return updatedPackagesWithDocPages; +} + +async function generateAndUploadDocJsonsAsync(packagesWithDocs: Package[], isStaging: boolean): Promise { + for (const pkg of packagesWithDocs) { + const nameWithoutPrefix = pkg.packageJson.name.replace('@0xproject/', ''); const shouldUploadDocs = true; const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); } } -async function confirmDocPagesRenderAsync(packages: Package[]): Promise { +async function confirmDocPagesRenderAsync(packagesWithDocs: Package[]): Promise { // push docs to staging utils.log("Upload all docJson's to S3 staging..."); const isStaging = true; - await generateAndUploadDocJsonsAsync(packages, isStaging); + await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging); // deploy website to staging utils.log('Deploy website to staging...'); const pathToWebsite = `${constants.monorepoRootPath}/packages/website`; await execAsync(`yarn deploy_staging`, { cwd: pathToWebsite }); - const packagesWithDocs = _.filter(packages, pkg => { - const scriptsIfExists = pkg.packageJson.scripts; - if (_.isUndefined(scriptsIfExists)) { - throw new Error('Found a public package without any scripts in package.json'); - } - return !_.isUndefined(scriptsIfExists[DOC_GEN_COMMAND]); - }); _.each(packagesWithDocs, pkg => { const name = pkg.packageJson.name; const nameWithoutPrefix = _.startsWith(name, NPM_NAMESPACE) ? name.split('@0xproject/')[1] : name; - const docSegmentIfExists = nameWithoutPrefix; - if (_.isUndefined(docSegmentIfExists)) { - throw new Error( - `Found package '${name}' with doc commands but no corresponding docSegment in monorepo_scripts -package.ts. Please add an entry for it and try again.`, - ); - } - const link = `${constants.stagingWebsite}/docs/${docSegmentIfExists}`; + const link = `${constants.stagingWebsite}/docs/${nameWithoutPrefix}`; // tslint:disable-next-line:no-floating-promises opn(link); }); - await confirmAsync('Do all the doc pages render properly? (y/n)'); + await confirmAsync('Do all the doc pages render? (y/n)'); } async function pushChangelogsToGithubAsync(): Promise { diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 1645ba0d6..5fee98b63 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -173,22 +173,12 @@ export class DocGenerateAndUploadUtils { throw new Error(`Couldn't find a package.json for ${packageName}`); } this._packageJson = pkg.packageJson; - this._omitExports = _.get(this._packageJson, 'config.postpublish.omitExports', []); + this._omitExports = _.get(this._packageJson, 'config.postpublish.docOmitExports', []); const indexPath = `${this._packagePath}/src/index.ts`; const exportInfo = DocGenerateAndUploadUtils._getExportPathToExportedItems(indexPath, this._omitExports); this._exportPathToExportedItems = exportInfo.exportPathToExportedItems; this._exportPathOrder = exportInfo.exportPathOrder; - - const shouldPublishDocs = !!_.get(this._packageJson, 'config.postpublish.shouldPublishDocs'); - if (!shouldPublishDocs) { - utils.log( - `GENERATE_UPLOAD_DOCS: ${ - this._packageJson.name - } packageJson.config.postpublish.shouldPublishDocs is false. Skipping doc JSON generation.`, - ); - return; - } } public async generateAndUploadDocsAsync(): Promise { // For each dep that is another one of our monorepo packages, we fetch it's index.ts -- cgit v1.2.3 From a6cdc38d532b897442bac74bc3fd1735c85317ba Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 23:25:06 +0100 Subject: Add/improve comments --- packages/monorepo-scripts/src/doc_gen_configs.ts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index fb6cc0886..6d7560943 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -1,7 +1,10 @@ import { DocGenConfigs } from './types'; export const docGenConfigs: DocGenConfigs = { + // Versions our doc JSON format so we can handle breaking changes intelligently DOC_JSON_VERSION: '0.0.1', + // Some types that are exposed by our package's public interface are external types. As such, we won't + // be able to render their definitions. Instead we link to them using this lookup. EXTERNAL_TYPE_TO_LINK: { Array: 'https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Array', BigNumber: 'http://mikemcl.github.io/bignumber.js', @@ -25,6 +28,9 @@ export const docGenConfigs: DocGenConfigs = { Schema: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/index.d.ts#L49', ValidatorResult: 'https://github.com/tdegrunt/jsonschema/blob/v1.2.4/lib/helpers.js#L31', }, + // Sometimes we want to hide a constructor from rendering in our docs. An example is when our library has a + // factory method which instantiates an instance of a class, but we don't want users instantiating it themselves + // and getting confused. Any class name in this list will not have it's constructor rendered in our docs. CLASSES_WITH_HIDDEN_CONSTRUCTORS: [ 'ERC20ProxyWrapper', 'ERC20TokenWrapper', -- cgit v1.2.3 From 2b38163274de9621160d54a8d809284c0b353cc4 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 13:56:40 +0100 Subject: Enable dry run of release publishing and handle git tags existing --- packages/monorepo-scripts/src/publish.ts | 12 ++++--- .../monorepo-scripts/src/publish_release_notes.ts | 13 ++++++- .../src/utils/github_release_utils.ts | 40 ++++++++++++++++------ 3 files changed, 49 insertions(+), 16 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 3b5070395..d27baf5f8 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -76,8 +76,10 @@ async function confirmAsync(message: string): Promise { utils.log(`Calling 'lerna publish'...`); await lernaPublishAsync(packageToNextVersion); const isStaging = false; - await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging); - await publishReleaseNotesAsync(updatedPublicPackages); + const shouldUploadDocs = !configs.IS_LOCAL_PUBLISH; + await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs); + const isDryRun = configs.IS_LOCAL_PUBLISH; + await publishReleaseNotesAsync(updatedPublicPackages, isDryRun); })().catch(err => { utils.log(err); process.exit(1); @@ -101,10 +103,9 @@ function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] { return updatedPackagesWithDocPages; } -async function generateAndUploadDocJsonsAsync(packagesWithDocs: Package[], isStaging: boolean): Promise { +async function generateAndUploadDocJsonsAsync(packagesWithDocs: Package[], isStaging: boolean, shouldUploadDocs: boolean): Promise { for (const pkg of packagesWithDocs) { const nameWithoutPrefix = pkg.packageJson.name.replace('@0xproject/', ''); - const shouldUploadDocs = true; const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); } @@ -114,7 +115,8 @@ async function confirmDocPagesRenderAsync(packagesWithDocs: Package[]): Promise< // push docs to staging utils.log("Upload all docJson's to S3 staging..."); const isStaging = true; - await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging); + const shouldUploadDocs = true; + await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs); // deploy website to staging utils.log('Deploy website to staging...'); diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 5afcc8775..1a0ec59e5 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -1,10 +1,21 @@ +import * as yargs from 'yargs'; + import { publishReleaseNotesAsync } from './utils/github_release_utils'; import { utils } from './utils/utils'; +const args = yargs + .option('isDryRun', { + describe: 'Whether we wish to do a dry run, not committing anything to Github', + type: 'boolean', + demandOption: true, + }) + .example('$0 --isDryRun true', 'Full usage example').argv; + // tslint:disable-next-line:no-floating-promises (async () => { + const isDryRun = args.isDryRun; const shouldIncludePrivate = false; const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); - await publishReleaseNotesAsync(allUpdatedPackages); + await publishReleaseNotesAsync(allUpdatedPackages, isDryRun); })(); diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 28dce70ac..43d0d9fc3 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -12,7 +12,7 @@ import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); // tslint:disable-next-line:completed-docs -export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { +export async function publishReleaseNotesAsync(updatedPublishPackages: Package[], isDryRun: boolean): Promise { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); const latestGitCommit = result.stdout; @@ -20,10 +20,22 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] const shortenedGitCommit = latestGitCommit.slice(0, prefixLength); const tagName = `monorepo@${shortenedGitCommit}`; - await execAsync(`git rev-parse ${tagName}`); - await execAsync(`git tag ${tagName}`); + if (!isDryRun) { + try { + await execAsync(`git tag ${tagName}`); + } catch (err) { + if (_.includes(err.message, 'already exists')) { + // Noop tag creation since already exists + } else { + throw err; + } + } + const {stdout} = await execAsync(`git ls-remote --tags origin refs/tags/${tagName}`); + if (_.isEmpty(stdout)) { + await execAsync(`git push origin ${tagName}`); + } + } - await execAsync(`git push origin ${tagName}`); const releaseName = `0x monorepo - ${shortenedGitCommit}`; let assets: string[] = []; @@ -42,11 +54,7 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] }); const finalAssets = adjustAssetPaths(assets); - utils.log('Publishing release notes ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 - await publishReleaseAsync({ + const publishReleaseConfigs = { token: constants.githubPersonalAccessToken, owner: '0xProject', tag: tagName, @@ -58,7 +66,19 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] reuseRelease: true, reuseDraftOnly: false, assets: finalAssets, - }); + }; + + if (isDryRun) { + utils.log(`Dry run: stopping short of publishing release notes to github`); + utils.log(`Would publish with configs:\n${JSON.stringify(publishReleaseConfigs, null, '\t')}`); + return; + } + + utils.log('Publishing release notes ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync(publishReleaseConfigs); } // Asset paths should described from the monorepo root. This method prefixes -- cgit v1.2.3 From 15a34dca790dc2ef25b302c2b2d50524865d2954 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 13:58:49 +0100 Subject: Fix prettier issues --- packages/monorepo-scripts/src/publish.ts | 6 +++++- packages/monorepo-scripts/src/utils/github_release_utils.ts | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index d27baf5f8..d9e09bdeb 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -103,7 +103,11 @@ function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] { return updatedPackagesWithDocPages; } -async function generateAndUploadDocJsonsAsync(packagesWithDocs: Package[], isStaging: boolean, shouldUploadDocs: boolean): Promise { +async function generateAndUploadDocJsonsAsync( + packagesWithDocs: Package[], + isStaging: boolean, + shouldUploadDocs: boolean, +): Promise { for (const pkg of packagesWithDocs) { const nameWithoutPrefix = pkg.packageJson.name.replace('@0xproject/', ''); const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging, shouldUploadDocs); diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 43d0d9fc3..9b5b26d7e 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -24,13 +24,13 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] try { await execAsync(`git tag ${tagName}`); } catch (err) { - if (_.includes(err.message, 'already exists')) { + if (_.includes(err.message, 'already exists')) { // Noop tag creation since already exists } else { throw err; } } - const {stdout} = await execAsync(`git ls-remote --tags origin refs/tags/${tagName}`); + const { stdout } = await execAsync(`git ls-remote --tags origin refs/tags/${tagName}`); if (_.isEmpty(stdout)) { await execAsync(`git push origin ${tagName}`); } -- cgit v1.2.3 From 0577ab96b8056b05dca1024227af53dad4ef5322 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 14:29:22 +0100 Subject: Upgrade Typedoc to 0.12.0, which works with TS 3.x --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 74be99550..551695129 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -65,7 +65,7 @@ "semver": "5.5.0", "semver-diff": "^2.1.0", "semver-sort": "0.0.4", - "typedoc": "0xProject/typedoc", + "typedoc": "0.12.0", "yargs": "^10.0.3" }, "publishConfig": { -- cgit v1.2.3 From f0f4f873a9226d55da8d5339a4918b74f281b1b9 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 14:29:32 +0100 Subject: Fix double assignment --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 5fee98b63..0768b14b5 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -77,7 +77,7 @@ export class DocGenerateAndUploadUtils { ); }); } else if (_.isObject(nodeValue)) { - updatedReferenceNames = updatedReferenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( + updatedReferenceNames = DocGenerateAndUploadUtils._getAllReferenceNames( innerPropertyName, nodeValue, updatedReferenceNames, -- cgit v1.2.3 From ae937cfcce0e751bc931a8f05df0b67b62962023 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 14:53:16 +0100 Subject: Add catch and exit with non-zero --- packages/monorepo-scripts/src/publish_release_notes.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 1a0ec59e5..13cf0d85d 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -11,11 +11,13 @@ const args = yargs }) .example('$0 --isDryRun true', 'Full usage example').argv; -// tslint:disable-next-line:no-floating-promises (async () => { const isDryRun = args.isDryRun; const shouldIncludePrivate = false; const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); await publishReleaseNotesAsync(allUpdatedPackages, isDryRun); -})(); +})().catch(err => { + utils.log(err); + process.exit(1); +}); -- cgit v1.2.3 From 29a9e1fc4ec6bc902dc8e76a4af712f2dff4ffb6 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 14:53:32 +0100 Subject: Look for all TS mapped types --- packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 0768b14b5..de52b3a47 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -56,12 +56,12 @@ export class DocGenerateAndUploadUtils { // Some nodes of type reference are for subtypes, which we don't want to return. // We therefore filter them out. const SUB_TYPE_PROPERTY_NAMES = ['inheritedFrom', 'overwrites', 'extendedTypes', 'implementationOf']; + const TS_MAPPED_TYPES = ['Partial', 'Promise', 'Readonly', 'Pick', 'Record']; if ( !_.isUndefined(node.type) && _.isString(node.type) && node.type === 'reference' && - node.name !== 'Partial' && - node.name !== 'Promise' && + !_.includes(TS_MAPPED_TYPES, node.name) && !_.includes(SUB_TYPE_PROPERTY_NAMES, propertyName) ) { updatedReferenceNames = _.uniq([...referenceNames, node.name]); -- cgit v1.2.3 From 610caef73faf735a9b9f38863acee007280151be Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 15:08:02 +0100 Subject: Fix comments --- packages/monorepo-scripts/src/utils/github_release_utils.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 9b5b26d7e..0f3485de0 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -65,6 +65,9 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] prerelease: false, reuseRelease: true, reuseDraftOnly: false, + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 assets: finalAssets, }; @@ -75,9 +78,6 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] } utils.log('Publishing release notes ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 await publishReleaseAsync(publishReleaseConfigs); } @@ -107,11 +107,6 @@ function getReleaseNotesForPackage(packageName: string, version: string): string if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { return ''; } - // We sanity check that the version for the changelog notes we are about to publish to Github - // correspond to the new version of the package. - // if (version !== latestLog.version) { - // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); - // } let notes = ''; _.each(latestLog.changes, change => { notes += `* ${change.note}`; -- cgit v1.2.3 From 029ea52979f9ba7347d20ec4fab962e1b79ee01f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 24 Aug 2018 18:58:12 +0100 Subject: Small fixes to publish script --- packages/monorepo-scripts/src/publish.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index d9e09bdeb..7e2e64536 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -18,7 +18,6 @@ import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils import { publishReleaseNotesAsync } from './utils/github_release_utils'; import { utils } from './utils/utils'; -const DOC_GEN_COMMAND = 'docs:json'; const NPM_NAMESPACE = '@0xproject/'; const TODAYS_TIMESTAMP = moment().unix(); @@ -88,7 +87,7 @@ async function confirmAsync(message: string): Promise { function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] { const rootPackageJsonPath = `${constants.monorepoRootPath}/package.json`; const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath).toString()); - const packagesWithDocPagesStringIfExist = _.get(rootPackageJson, 'configs.packagesWithDocPages', undefined); + const packagesWithDocPagesStringIfExist = _.get(rootPackageJson, 'config.packagesWithDocPages', undefined); if (_.isUndefined(packagesWithDocPagesStringIfExist)) { return []; // None to generate & publish } -- cgit v1.2.3 From 7f585a15f526e0a61fd822cdefb7087fc6bb8934 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 24 Aug 2018 19:11:27 +0100 Subject: Publish - 0x.js@1.0.1-rc.4 - @0xproject/abi-gen@1.0.6 - @0xproject/assert@1.0.6 - @0xproject/base-contract@2.0.0 - @0xproject/connect@2.0.0-rc.1 - @0xproject/contract-wrappers@1.0.1-rc.4 - contracts@2.1.41 - @0xproject/dev-utils@1.0.5 - ethereum-types@1.0.5 - @0xproject/fill-scenarios@1.0.1-rc.4 - @0xproject/forwarder-helper@1.0.1-rc.1 - @0xproject/json-schemas@1.0.1-rc.5 - @0xproject/metacoin@0.0.16 - @0xproject/migrations@1.0.5 - @0xproject/monorepo-scripts@1.0.6 - @0xproject/order-utils@1.0.1-rc.4 - @0xproject/order-watcher@1.0.1-rc.4 - @0xproject/react-docs@1.0.6 - @0xproject/react-shared@1.0.7 - @0xproject/sol-compiler@1.1.0 - @0xproject/sol-cov@2.1.0 - @0xproject/sol-resolver@1.0.6 - @0xproject/sra-api@1.0.1-rc.5 - @0xproject/sra-report@1.0.6 - @0xproject/subproviders@2.0.0 - @0xproject/testnet-faucets@1.0.42 - @0xproject/tslint-config@1.0.6 - @0xproject/types@1.0.1-rc.5 - @0xproject/typescript-typings@1.0.5 - @0xproject/utils@1.0.6 - @0xproject/web3-wrapper@2.0.0 - @0xproject/website@0.0.45 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 551695129..6a4d0bb45 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From 09d64961359cb63ff0bf1496b5f30840f030d8db Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 26 Aug 2018 20:53:21 +0100 Subject: Change exit code to failure --- packages/monorepo-scripts/src/test_installation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index 87c4ad1d7..e626fb891 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -85,7 +85,7 @@ function logIfDefined(x: any): void { logIfDefined(packageError.error.stdout); logIfDefined(packageError.error.stack); }); - process.exit(0); + process.exit(1); } })().catch(err => { utils.log(`Unexpected error: ${err.message}`); -- cgit v1.2.3 From 40cf805e5ec0b49b6b193bad941b97049864ba0b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 26 Aug 2018 20:54:15 +0100 Subject: Also use failure exit code if unexpected error occurs --- packages/monorepo-scripts/src/test_installation.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index e626fb891..10709af25 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -86,10 +86,12 @@ function logIfDefined(x: any): void { logIfDefined(packageError.error.stack); }); process.exit(1); + } else { + process.exit(0); } })().catch(err => { utils.log(`Unexpected error: ${err.message}`); - process.exit(0); + process.exit(1); }); async function testInstallPackageAsync( -- cgit v1.2.3 From 52fde551e47c774c115c6b6fae085025dc742196 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 26 Aug 2018 21:16:32 +0100 Subject: Remove check since this method is now used in multiple places --- packages/monorepo-scripts/src/utils/changelog_utils.ts | 5 ----- 1 file changed, 5 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/changelog_utils.ts b/packages/monorepo-scripts/src/utils/changelog_utils.ts index 4781b3b7d..8058d222b 100644 --- a/packages/monorepo-scripts/src/utils/changelog_utils.ts +++ b/packages/monorepo-scripts/src/utils/changelog_utils.ts @@ -19,11 +19,6 @@ CHANGELOG export const changelogUtils = { getChangelogMdTitle(versionChangelog: VersionChangelog): string { - if (_.isUndefined(versionChangelog.timestamp)) { - throw new Error( - 'All CHANGELOG.json entries must be updated to include a timestamp before generating their MD version', - ); - } const date = moment(`${versionChangelog.timestamp}`, 'X').format('MMMM D, YYYY'); const title = `\n## v${versionChangelog.version} - _${date}_\n\n`; return title; -- cgit v1.2.3 From 6174d9ebb78b46d98a3e994ae00eea05a92bc84a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 27 Aug 2018 12:34:34 +0100 Subject: Fix typo --- packages/monorepo-scripts/src/test_installation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index 10709af25..be39b1878 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -146,7 +146,7 @@ async function testInstallPackageAsync( 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`); + utils.log(`Successfully ran test script with ${packageName} imported`); } await rimrafAsync(testDirectory); } -- cgit v1.2.3 From bc4149683e2dda2b36c29cc81fadf1ae4de7d8b1 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 27 Aug 2018 12:39:10 +0100 Subject: Skip doc generation for local publishes since we test this in a separate CI test --- packages/monorepo-scripts/src/publish.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 7e2e64536..646818c58 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -74,9 +74,11 @@ async function confirmAsync(message: string): Promise { }); utils.log(`Calling 'lerna publish'...`); await lernaPublishAsync(packageToNextVersion); - const isStaging = false; - const shouldUploadDocs = !configs.IS_LOCAL_PUBLISH; - await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs); + if (!configs.IS_LOCAL_PUBLISH) { + const isStaging = false; + const shouldUploadDocs = true; + await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs); + } const isDryRun = configs.IS_LOCAL_PUBLISH; await publishReleaseNotesAsync(updatedPublicPackages, isDryRun); })().catch(err => { -- cgit v1.2.3 From 00a4fa5f7c1da8deae703b36b6bbed024cf9e111 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 27 Aug 2018 14:48:24 +0100 Subject: Publish - 0x.js@1.0.1-rc.6 - @0xproject/abi-gen@1.0.7 - @0xproject/assert@1.0.7 - @0xproject/base-contract@2.0.1 - @0xproject/connect@2.0.0-rc.2 - @0xproject/contract-wrappers@1.0.1-rc.5 - contracts@2.1.42 - @0xproject/dev-utils@1.0.6 - @0xproject/fill-scenarios@1.0.1-rc.5 - @0xproject/forwarder-helper@1.0.1-rc.2 - @0xproject/json-schemas@1.0.1-rc.6 - @0xproject/metacoin@0.0.17 - @0xproject/migrations@1.0.6 - @0xproject/monorepo-scripts@1.0.7 - @0xproject/order-utils@1.0.1-rc.6 - @0xproject/order-watcher@1.0.1-rc.5 - @0xproject/react-docs@1.0.7 - @0xproject/react-shared@1.0.8 - @0xproject/sol-compiler@1.1.1 - @0xproject/sol-cov@2.1.1 - @0xproject/sol-resolver@1.0.7 - @0xproject/sra-report@1.0.7 - @0xproject/sra-spec@1.0.1-rc.6 - @0xproject/subproviders@2.0.1 - @0xproject/testnet-faucets@1.0.43 - @0xproject/types@1.0.1-rc.6 - @0xproject/utils@1.0.7 - @0xproject/web3-wrapper@2.0.1 - @0xproject/website@0.0.46 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 6a4d0bb45..a2f2343b8 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.6", + "version": "1.0.7", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From f4a4fefe422a5b2140d5bb394a7f06f842352c69 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 27 Aug 2018 15:02:12 +0100 Subject: Exit with non-error code at end of publishRelease --- packages/monorepo-scripts/src/publish_release_notes.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 13cf0d85d..a9bc8fe75 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -17,6 +17,7 @@ const args = yargs const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); await publishReleaseNotesAsync(allUpdatedPackages, isDryRun); + process.exit(0); })().catch(err => { utils.log(err); process.exit(1); -- cgit v1.2.3 From 9c4c4fb19ac14d19a1f13e1a2a9b3b8ca1fa83bc Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Tue, 28 Aug 2018 12:03:21 -0700 Subject: Export missing types and add OrderValidatorWrapper to hidden constructors --- packages/monorepo-scripts/src/doc_gen_configs.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 6d7560943..102b5d7ca 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -39,6 +39,7 @@ export const docGenConfigs: DocGenConfigs = { 'EtherTokenWrapper', 'ExchangeWrapper', 'ForwarderWrapper', + 'OrderValidatorWrapper', 'TransactionEncoder', ], // Some types are not explicitly part of the public interface like params, return values, etc... But we still -- cgit v1.2.3 From e7d5ceb9c5487a5851dbfc1f8bdbe0182fedaef2 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Wed, 29 Aug 2018 11:15:30 -0700 Subject: feat: Add support for TypeScript project references (#991) * Update all package.json and tsconfig.json * fix(contracts): Make test/utils/web3_wrapper.ts compatible with project refs * Fix webpack config for 0x.js * Fix linter errors by adding rootDir to tsconfig.json as needed * Add build:ts and watch:ts commands to package.json * Update sra-spec to work with project references * Update tsconfig.json with latest new/removed packages * Add TypeScript as devDependency at root * Add missing rootDir to forwarder-helper package * Use a separate tsconfig file for typedoc * Fix linter errors * Apply PR feedback (add comments) * Fix 0x.js tsconfig --- packages/monorepo-scripts/package.json | 3 +-- packages/monorepo-scripts/tsconfig.json | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index a2f2343b8..f1d0ff29c 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -9,8 +9,7 @@ "main": "lib/index.js", "types": "lib/index.d.ts", "scripts": { - "watch_without_deps": "tsc -w", - "build": "tsc", + "build": "tsc -b", "lint": "tslint --project .", "clean": "shx rm -rf lib", "test:publish": "run-s build script:publish", diff --git a/packages/monorepo-scripts/tsconfig.json b/packages/monorepo-scripts/tsconfig.json index 332d3a5e1..c8b1d23e5 100644 --- a/packages/monorepo-scripts/tsconfig.json +++ b/packages/monorepo-scripts/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../tsconfig", "compilerOptions": { "typeRoots": ["../../node_modules/@types", "node_modules/@types"], - "outDir": "lib" + "outDir": "lib", + "rootDir": "src" }, "include": ["./src/**/*"] } -- cgit v1.2.3 From 77acbdd3ea9067856d0ece5fc2adc9609c480c9c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 4 Sep 2018 14:52:17 +0200 Subject: Remove types for ganache-core from typescript-typings --- packages/monorepo-scripts/src/doc_gen_configs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 102b5d7ca..b682f3f7b 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -17,7 +17,7 @@ export const docGenConfigs: DocGenConfigs = { 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', Uint8Array: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array', 'Ganache.GanacheOpts': - 'https://github.com/0xProject/0x-monorepo/blob/ddf85112d7e4eb1581e0d82ce6eedad429641106/packages/typescript-typings/types/ganache-core/index.d.ts#L3', + 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ganache-core/index.d.ts#L8', 'lightwallet.keystore': 'https://github.com/0xProject/0x-monorepo/blob/ddf85112d7e4eb1581e0d82ce6eedad429641106/packages/typescript-typings/types/eth-lightwallet/index.d.ts#L32', }, -- cgit v1.2.3 From 3ea137a78f949f09cb8159e6ef59b8ec0ab3c2a5 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 4 Sep 2018 15:04:42 +0200 Subject: Remove types for eth-lightwallet from typescript-typings --- packages/monorepo-scripts/src/doc_gen_configs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index b682f3f7b..951e4fd45 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -19,7 +19,7 @@ export const docGenConfigs: DocGenConfigs = { 'Ganache.GanacheOpts': 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ganache-core/index.d.ts#L8', 'lightwallet.keystore': - 'https://github.com/0xProject/0x-monorepo/blob/ddf85112d7e4eb1581e0d82ce6eedad429641106/packages/typescript-typings/types/eth-lightwallet/index.d.ts#L32', + 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eth-lightwallet/index.d.ts#L36', }, // If a 0x package re-exports an external package, we should add a link to it's exported items here EXTERNAL_EXPORT_TO_LINK: { -- cgit v1.2.3 From 6b41a570a5fc14723a6d52a328fd7e532da1e0e2 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 4 Sep 2018 16:30:08 +0200 Subject: Change doc gen configs --- packages/monorepo-scripts/src/doc_gen_configs.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 951e4fd45..e3ddeddc9 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -16,10 +16,8 @@ export const docGenConfigs: DocGenConfigs = { Schema: 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', Uint8Array: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array', - 'Ganache.GanacheOpts': - 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ganache-core/index.d.ts#L8', - 'lightwallet.keystore': - 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eth-lightwallet/index.d.ts#L36', + GanacheOpts: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ganache-core/index.d.ts#L8', + keystore: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eth-lightwallet/index.d.ts#L36', }, // If a 0x package re-exports an external package, we should add a link to it's exported items here EXTERNAL_EXPORT_TO_LINK: { -- cgit v1.2.3 From 174b36059368631eeaec3ec7c0a3847350b55d73 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 5 Sep 2018 11:16:45 +0100 Subject: Publish - 0x.js@1.0.1 - @0xproject/abi-gen@1.0.8 - @0xproject/assert@1.0.8 - @0xproject/base-contract@2.0.2 - @0xproject/connect@2.0.0 - @0xproject/contract-wrappers@1.0.1 - contracts@2.1.43 - @0xproject/dev-utils@1.0.7 - ethereum-types@1.0.6 - @0xproject/fill-scenarios@1.0.1 - @0xproject/forwarder-helper@1.0.1 - @0xproject/json-schemas@1.0.1 - @0xproject/metacoin@0.0.18 - @0xproject/migrations@1.0.7 - @0xproject/monorepo-scripts@1.0.8 - @0xproject/order-utils@1.0.1 - @0xproject/order-watcher@1.0.1 - @0xproject/react-docs@1.0.8 - @0xproject/react-shared@1.0.9 - @0xproject/sol-compiler@1.1.2 - @0xproject/sol-cov@2.1.2 - @0xproject/sol-resolver@1.0.8 - @0xproject/sra-report@1.0.8 - @0xproject/sra-spec@1.0.1 - @0xproject/subproviders@2.0.2 - @0xproject/testnet-faucets@1.0.44 - @0xproject/tslint-config@1.0.7 - @0xproject/types@1.0.1 - @0xproject/typescript-typings@2.0.0 - @0xproject/utils@1.0.8 - @0xproject/web3-wrapper@2.0.2 - @0xproject/website@0.0.47 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index f1d0ff29c..cddb6ec3d 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.7", + "version": "1.0.8", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From 7dd28d6fab1d47a287422a0f51d63ba69d1c4dbc Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 21 Sep 2018 16:37:20 +0200 Subject: Don't depend on a specific version of node types --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index cddb6ec3d..571865a90 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -33,7 +33,7 @@ "devDependencies": { "@types/glob": "^5.0.33", "@types/mkdirp": "^0.5.2", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/opn": "^5.1.0", "@types/rimraf": "^2.0.2", "@types/semver": "5.5.0", -- cgit v1.2.3 From 29f6adc2ed57720d2c2aab7b760a4bcfec5d7b37 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 21 Sep 2018 16:59:27 +0200 Subject: Publish - 0x.js@1.0.4 - @0xproject/abi-gen@1.0.9 - @0xproject/assert@1.0.9 - @0xproject/base-contract@2.0.3 - @0xproject/connect@2.0.2 - @0xproject/contract-wrappers@1.0.4 - contracts@2.1.45 - @0xproject/dev-utils@1.0.8 - ethereum-types@1.0.7 - @0xproject/fill-scenarios@1.0.3 - @0xproject/forwarder-helper@1.0.4 - @0xproject/json-schemas@1.0.2 - @0xproject/metacoin@0.0.19 - @0xproject/migrations@1.0.10 - @0xproject/monorepo-scripts@1.0.9 - @0xproject/order-utils@1.0.3 - @0xproject/order-watcher@1.0.4 - @0xproject/react-docs@1.0.9 - @0xproject/react-shared@1.0.10 - @0xproject/sol-compiler@1.1.3 - @0xproject/sol-cov@2.1.3 - @0xproject/sol-resolver@1.0.9 - @0xproject/sra-report@1.0.9 - @0xproject/sra-spec@1.0.2 - @0xproject/subproviders@2.0.3 - @0xproject/testnet-faucets@1.0.47 - @0xproject/types@1.0.2 - @0xproject/typescript-typings@2.0.1 - @0xproject/utils@1.0.9 - @0xproject/web3-wrapper@2.0.3 - @0xproject/website@0.0.50 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 571865a90..e776569b1 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.8", + "version": "1.0.9", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From f33ecfd2fcff106c673c5f96350e12f831b3295f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 26 Sep 2018 13:11:12 +0100 Subject: Support passing in package names into publish_release_notes command-line for when publishing must be done manually --- .../monorepo-scripts/src/publish_release_notes.ts | 20 ++++++++++++++++---- packages/monorepo-scripts/src/utils/utils.ts | 7 +++++++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index a9bc8fe75..101ac87b4 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -1,3 +1,4 @@ +import * as _ from 'lodash'; import * as yargs from 'yargs'; import { publishReleaseNotesAsync } from './utils/github_release_utils'; @@ -9,14 +10,25 @@ const args = yargs type: 'boolean', demandOption: true, }) - .example('$0 --isDryRun true', 'Full usage example').argv; + .option('packages', { + describe: + 'Space-separated list of packages to generated release notes for. If not supplied, it does all `Lerna updated` packages', + type: 'string', + }) + .example('$0 --isDryRun true --packages "0x.js @0xproject/web3-wrapper"', 'Full usage example').argv; (async () => { const isDryRun = args.isDryRun; - const shouldIncludePrivate = false; - const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + let packages; + if (_.isUndefined(args.packages)) { + const shouldIncludePrivate = false; + packages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + } else { + const packageNames = args.packages.split(' '); + packages = await utils.getPackagesByNameAsync(packageNames); + } - await publishReleaseNotesAsync(allUpdatedPackages, isDryRun); + await publishReleaseNotesAsync(packages, isDryRun); process.exit(0); })().catch(err => { utils.log(err); diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 2ce36942c..5e2e877c7 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -54,6 +54,13 @@ export const utils = { } return packages; }, + async getPackagesByNameAsync(packageNames: string[]): Promise { + const allPackages = utils.getPackages(constants.monorepoRootPath); + const updatedPackages = _.filter(allPackages, pkg => { + return _.includes(packageNames, pkg.packageJson.name); + }); + return updatedPackages; + }, async getUpdatedPackagesAsync(shouldIncludePrivate: boolean): Promise { const updatedPublicPackages = await utils.getLernaUpdatedPackagesAsync(shouldIncludePrivate); const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); -- cgit v1.2.3 From f8532b3f51a5bb4f4294606c495321a82d71c69d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 26 Sep 2018 13:15:42 +0100 Subject: Typo --- packages/monorepo-scripts/src/publish_release_notes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 101ac87b4..6090498e0 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -12,7 +12,7 @@ const args = yargs }) .option('packages', { describe: - 'Space-separated list of packages to generated release notes for. If not supplied, it does all `Lerna updated` packages', + 'Space-separated list of packages to generated release notes for. If not supplied, it does all `Lerna updated` packages.', type: 'string', }) .example('$0 --isDryRun true --packages "0x.js @0xproject/web3-wrapper"', 'Full usage example').argv; -- cgit v1.2.3 From ac14dd2b29b42ef4d2a46db9b70d4d30cf9bd40f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 28 Sep 2018 19:16:07 +0100 Subject: Publish - 0x.js@1.0.7 - @0xproject/abi-gen@1.0.12 - @0xproject/assert@1.0.12 - @0xproject/asset-buyer@1.0.2 - @0xproject/base-contract@3.0.0 - @0xproject/connect@3.0.0 - @0xproject/contract-wrappers@2.0.1 - contracts@2.1.48 - @0xproject/dev-utils@1.0.11 - ethereum-types@1.0.9 - @0xproject/fill-scenarios@1.0.6 - @0xproject/json-schemas@1.0.5 - @0xproject/metacoin@0.0.22 - @0xproject/migrations@1.0.13 - @0xproject/monorepo-scripts@1.0.10 - @0xproject/order-utils@1.0.6 - @0xproject/order-watcher@2.1.0 - @0xproject/react-docs@1.0.12 - @0xproject/react-shared@1.0.13 - @0xproject/sol-compiler@1.1.6 - @0xproject/sol-cov@2.1.6 - @0xproject/sol-doc@1.0.1 - @0xproject/sol-resolver@1.0.12 - @0xproject/sra-report@1.0.12 - @0xproject/sra-spec@1.0.5 - @0xproject/subproviders@2.0.6 - @0xproject/testnet-faucets@1.0.50 - @0xproject/types@1.1.2 - @0xproject/typescript-typings@3.0.0 - @0xproject/utils@2.0.0 - @0xproject/web3-wrapper@3.0.2 - @0xproject/website@0.0.53 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index e776569b1..748b88f6a 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From f4e4eef48e703afb923ba4f969fc77f32be81745 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 1 Oct 2018 16:37:35 +0200 Subject: Introduce a build:ci command that doesn't build webpack bundles --- packages/monorepo-scripts/package.json | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 748b88f6a..ba4c4fead 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -10,6 +10,7 @@ "types": "lib/index.d.ts", "scripts": { "build": "tsc -b", + "build:ci": "yarn build", "lint": "tslint --project .", "clean": "shx rm -rf lib", "test:publish": "run-s build script:publish", -- cgit v1.2.3 From b5d88079d9876677ff983f02f55d8f98bc7ab439 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 4 Oct 2018 15:52:06 -0700 Subject: Publish - 0x.js@1.0.8 - @0xproject/abi-gen@1.0.13 - @0xproject/assert@1.0.13 - @0xproject/asset-buyer@2.0.0 - @0xproject/base-contract@3.0.1 - @0xproject/connect@3.0.1 - @0xproject/contract-wrappers@2.0.2 - contracts@2.1.49 - @0xproject/dev-utils@1.0.12 - ethereum-types@1.0.11 - @0xproject/fill-scenarios@1.0.7 - @0xproject/instant@0.0.2 - @0xproject/json-schemas@1.0.7 - @0xproject/metacoin@0.0.23 - @0xproject/migrations@1.0.14 - @0xproject/monorepo-scripts@1.0.11 - @0xproject/order-utils@1.0.7 - @0xproject/order-watcher@2.1.1 - @0xproject/react-docs@1.0.13 - @0xproject/react-shared@1.0.15 - @0xproject/sol-compiler@1.1.7 - @0xproject/sol-cov@2.1.7 - @0xproject/sol-doc@1.0.2 - @0xproject/sol-resolver@1.0.14 - @0xproject/sra-report@1.0.13 - @0xproject/sra-spec@1.0.6 - @0xproject/subproviders@2.0.7 - @0xproject/testnet-faucets@1.0.51 - @0xproject/tslint-config@1.0.8 - @0xproject/types@1.1.4 - @0xproject/typescript-typings@3.0.2 - @0xproject/utils@2.0.2 - @0xproject/web3-wrapper@3.0.3 - @0xproject/website@0.0.54 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index ba4c4fead..83091ae84 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.10", + "version": "1.0.11", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From 24673be1cd2ec0b86ecb9b8b5eb8f69197e763d1 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Fri, 12 Oct 2018 14:59:47 -0700 Subject: Add resolveJsonModule: true to test_installation.ts --- packages/monorepo-scripts/src/test_installation.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index be39b1878..f272c9292 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -132,6 +132,7 @@ async function testInstallPackageAsync( noImplicitReturns: true, pretty: true, strict: true, + resolveJsonModule: true, }, include: ['index.ts'], }; -- cgit v1.2.3 From f0e483798339b24b599c408949265cca54d7e58b Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Mon, 15 Oct 2018 13:30:12 -0700 Subject: Fix failing doc generation tests --- .../src/utils/doc_generate_and_upload_utils.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index de52b3a47..4fea94414 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -1,4 +1,4 @@ -import { readFileSync, writeFileSync } from 'fs'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; import * as _ from 'lodash'; import * as path from 'path'; import { exec as execAsync } from 'promisify-child-process'; @@ -103,6 +103,9 @@ export class DocGenerateAndUploadUtils { switch (node.kind) { case ts.SyntaxKind.ExportDeclaration: { const exportClause = (node as any).exportClause; + if (_.isUndefined(exportClause)) { + return; + } const exportPath = exportClause.parent.moduleSpecifier.text; _.each(exportClause.elements, element => { const exportItem = element.name.escapedText; @@ -187,7 +190,11 @@ export class DocGenerateAndUploadUtils { const typeDocExtraFileIncludes: string[] = this._getTypeDocFileIncludesForPackage(); // In order to avoid TS errors, we need to pass TypeDoc the package's global.d.ts file - typeDocExtraFileIncludes.push(path.join(this._packagePath, 'src', 'globals.d.ts')); + // if it exists. + const globalTypeDefinitionsPath = path.join(this._packagePath, 'src', 'globals.d.ts'); + if (existsSync(globalTypeDefinitionsPath)) { + typeDocExtraFileIncludes.push(globalTypeDefinitionsPath); + } utils.log(`GENERATE_UPLOAD_DOCS: Generating Typedoc JSON for ${this._packageName}...`); const jsonFilePath = path.join(this._packagePath, 'generated_docs', 'index.json'); -- cgit v1.2.3 From 8cffe65047ed193b52ccacc346ce8ad1983f02f4 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 16 Oct 2018 13:22:15 +0100 Subject: fix(monorepo-scripts): Move the creation of the `.installation-test` directory OUTSIDE of the monorepo root, so that the installed packages can't reference the hoisted node_modules folder --- packages/monorepo-scripts/src/test_installation.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index f272c9292..9ef9e829b 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -104,13 +104,7 @@ async function testInstallPackageAsync( 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, - ); + const testDirectory = path.join(monorepoRootPath, '..', '.installation-test', packageDirName); await rimrafAsync(testDirectory); await mkdirpAsync(testDirectory); await execAsync('yarn init --yes', { cwd: testDirectory }); -- cgit v1.2.3 From 72f5719b3412da7840a7b85e4dce512ecbaece4d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 16 Oct 2018 15:17:49 +0100 Subject: Added note about restriction on `testDirectory` --- packages/monorepo-scripts/src/test_installation.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index 9ef9e829b..a642498ac 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -104,6 +104,9 @@ async function testInstallPackageAsync( const packageName = installablePackage.packageJson.name; utils.log(`Testing ${packageName}@${lastChangelogVersion}`); const packageDirName = path.join(...(packageName + '-test').split('/')); + // NOTE(fabio): The `testDirectory` needs to be somewhere **outside** the monorepo root directory. + // Otherwise, it will have access to the hoisted `node_modules` directory and the Typescript missing + // type errors will not be caught. const testDirectory = path.join(monorepoRootPath, '..', '.installation-test', packageDirName); await rimrafAsync(testDirectory); await mkdirpAsync(testDirectory); -- cgit v1.2.3 From 2c286ad897d7ae9f2dcc48919033fb0d1c026641 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 15 Oct 2018 10:51:38 -0700 Subject: feat(monorepo-scripts): add AssetBuyerError to IGNORED_EXCESSIVE_TYPES --- packages/monorepo-scripts/CHANGELOG.json | 8 ++++++++ packages/monorepo-scripts/src/doc_gen_configs.ts | 8 +++++++- .../monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json index 3b8684fab..4fd87c1d8 100644 --- a/packages/monorepo-scripts/CHANGELOG.json +++ b/packages/monorepo-scripts/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "1.0.6", + "changes": [ + { + "note": "Add AssetBuyerError to the IGNORED_EXCESSIVE_TYPES array" + } + ] + }, { "timestamp": 1534210131, "version": "1.0.5", diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index e3ddeddc9..3d5c97dc4 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -43,7 +43,13 @@ export const docGenConfigs: DocGenConfigs = { // Some types are not explicitly part of the public interface like params, return values, etc... But we still // want them exported. E.g error enum types that can be thrown by methods. These must be manually added to this // config - IGNORED_EXCESSIVE_TYPES: ['NonceSubproviderErrors', 'Web3WrapperErrors', 'ContractWrappersError', 'OrderError'], + IGNORED_EXCESSIVE_TYPES: [ + 'NonceSubproviderErrors', + 'Web3WrapperErrors', + 'ContractWrappersError', + 'OrderError', + 'AssetBuyerError', + ], // Some libraries only export types. In those cases, we cannot check if the exported types are part of the // "exported public interface". Thus we add them here and skip those checks. TYPES_ONLY_LIBRARIES: ['ethereum-types', 'types'], diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 4fea94414..547b65eeb 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -331,7 +331,7 @@ export class DocGenerateAndUploadUtils { throw new Error( `${this._packageName} package exports BUT does not need: \n${excessiveReferencesExceptIgnored.join( '\n', - )} \nin it\'s index.ts. Remove them then try again.`, + )} \nin it\'s index.ts. Remove them then try again OR if we still want them exported (e.g error enum types), then add them to the IGNORED_EXCESSIVE_TYPES array.`, ); } } -- cgit v1.2.3 From 55be070dcfd7b9704ba24bc387bca0001f0c47f5 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 15 Oct 2018 22:28:29 -0700 Subject: feat(monorepo-scripts): add AssetBuyer to CLASSES_WITH_HIDDEN_CONSTRUCTORS --- packages/monorepo-scripts/src/doc_gen_configs.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 3d5c97dc4..b5a36376a 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -30,6 +30,7 @@ export const docGenConfigs: DocGenConfigs = { // factory method which instantiates an instance of a class, but we don't want users instantiating it themselves // and getting confused. Any class name in this list will not have it's constructor rendered in our docs. CLASSES_WITH_HIDDEN_CONSTRUCTORS: [ + 'AssetBuyer', 'ERC20ProxyWrapper', 'ERC20TokenWrapper', 'ERC721ProxyWrapper', -- cgit v1.2.3 From 0013bafc62571bc81f2984974c4893c3770b1786 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 17 Oct 2018 14:14:48 +1100 Subject: fix(monorepo-scripts): Format date as UTC not local time. Down under is in the future and causes many conflicts when formatting the timestamp in the local context. All previous releases jumped a day ahead. By setting this to UTC we will have consistent formatted dates in the changelogs no matter where one publishes from. npm-cli-login fails on node 10 as a deprecation in node 9 has finished. This package appears to be unmaintained so we now have a fork with a fix --- packages/monorepo-scripts/CHANGELOG.json | 9 +++++++++ packages/monorepo-scripts/src/utils/changelog_utils.ts | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json index 3b8684fab..cf7a22bb7 100644 --- a/packages/monorepo-scripts/CHANGELOG.json +++ b/packages/monorepo-scripts/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "1.0.6", + "changes": [ + { + "note": "Render date formats in UTC to prevent conflicts when publishing in different timezones.", + "pr": 1143 + } + ] + }, { "timestamp": 1534210131, "version": "1.0.5", diff --git a/packages/monorepo-scripts/src/utils/changelog_utils.ts b/packages/monorepo-scripts/src/utils/changelog_utils.ts index 8058d222b..0b46bf670 100644 --- a/packages/monorepo-scripts/src/utils/changelog_utils.ts +++ b/packages/monorepo-scripts/src/utils/changelog_utils.ts @@ -19,7 +19,8 @@ CHANGELOG export const changelogUtils = { getChangelogMdTitle(versionChangelog: VersionChangelog): string { - const date = moment(`${versionChangelog.timestamp}`, 'X').format('MMMM D, YYYY'); + // Use UTC rather than the local machines time (formatted date time is +0:00) + const date = moment.utc(`${versionChangelog.timestamp}`, 'X').format('MMMM D, YYYY'); const title = `\n## v${versionChangelog.version} - _${date}_\n\n`; return title; }, -- cgit v1.2.3 From 7c87d2e38b070fa9c3f2704c60f4e886d921cda3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 17 Oct 2018 16:18:28 +0100 Subject: chore: Update TypeDoc to 0.13.0 (supports TS v3.1) --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 83091ae84..57e8bc147 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -65,7 +65,7 @@ "semver": "5.5.0", "semver-diff": "^2.1.0", "semver-sort": "0.0.4", - "typedoc": "0.12.0", + "typedoc": "0.13.0", "yargs": "^10.0.3" }, "publishConfig": { -- cgit v1.2.3 From 02cf99fa367f8058447a0a05b1d148afb68ab85c Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 18 Oct 2018 11:07:00 +1100 Subject: fix(order-utils): remove constants export --- packages/monorepo-scripts/src/doc_gen_configs.ts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index b5a36376a..0aaf5a6a5 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -16,8 +16,14 @@ export const docGenConfigs: DocGenConfigs = { Schema: 'https://github.com/tdegrunt/jsonschema/blob/5c2edd4baba149964aec0f23c87ad12c25a50dfb/lib/index.d.ts#L49', Uint8Array: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array', + // HACK: CI can handle these without the namespace but some local setups (Jacob) require the namespace prefix + // This is duplicated until we can discover the source of the issue. GanacheOpts: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ganache-core/index.d.ts#L8', keystore: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eth-lightwallet/index.d.ts#L36', + 'Ganache.GanacheOpts': + 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ganache-core/index.d.ts#L8', + 'lightwallet.keystore': + 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eth-lightwallet/index.d.ts#L36', }, // If a 0x package re-exports an external package, we should add a link to it's exported items here EXTERNAL_EXPORT_TO_LINK: { -- cgit v1.2.3 From f8876ab60b5e8fa606073d6c48aa1395dbadd88b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 18 Oct 2018 13:15:39 +0200 Subject: Remove sra-report --- packages/monorepo-scripts/src/test_installation.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index a642498ac..459f70839 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -12,12 +12,7 @@ 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. -const UNRUNNABLE_PACKAGES = [ - '@0xproject/abi-gen', - '@0xproject/sra-report', - '@0xproject/react-shared', - '@0xproject/react-docs', -]; +const UNRUNNABLE_PACKAGES = ['@0xproject/abi-gen', '@0xproject/react-shared', '@0xproject/react-docs']; const mkdirpAsync = promisify(mkdirp); const rimrafAsync = promisify(rimraf); -- cgit v1.2.3 From 9f924e459c43c023e35ab7222cd9824cc0e67411 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 18 Oct 2018 21:51:56 +1100 Subject: chore: change package org from 0xproject to 0x --- packages/monorepo-scripts/package.json | 2 +- packages/monorepo-scripts/src/find_unused_dependencies.ts | 2 +- packages/monorepo-scripts/src/publish.ts | 8 ++++---- packages/monorepo-scripts/src/publish_release_notes.ts | 2 +- packages/monorepo-scripts/src/test_installation.ts | 4 ++-- .../monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts | 4 ++-- packages/monorepo-scripts/src/utils/github_release_utils.ts | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 57e8bc147..3a783af9b 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,6 +1,6 @@ { "private": true, - "name": "@0xproject/monorepo-scripts", + "name": "@0x/monorepo-scripts", "version": "1.0.11", "engines": { "node": ">=6.12" diff --git a/packages/monorepo-scripts/src/find_unused_dependencies.ts b/packages/monorepo-scripts/src/find_unused_dependencies.ts index 4bb4b7dc5..42b4b7890 100644 --- a/packages/monorepo-scripts/src/find_unused_dependencies.ts +++ b/packages/monorepo-scripts/src/find_unused_dependencies.ts @@ -7,7 +7,7 @@ import { constants } from './constants'; import { utils } from './utils/utils'; // For some reason, `depcheck` hangs on some packages. Add them here. -const IGNORE_PACKAGES = ['@0xproject/sol-compiler']; +const IGNORE_PACKAGES = ['@0x/sol-compiler']; (async () => { utils.log('*** NOTE: Not all deps listed here are actually not required. ***'); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 646818c58..c1a6b9d7f 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -18,7 +18,7 @@ import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils import { publishReleaseNotesAsync } from './utils/github_release_utils'; import { utils } from './utils/utils'; -const NPM_NAMESPACE = '@0xproject/'; +const NPM_NAMESPACE = '@0x/'; const TODAYS_TIMESTAMP = moment().unix(); async function confirmAsync(message: string): Promise { @@ -96,7 +96,7 @@ function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] { const packagesWithDocPages = packagesWithDocPagesStringIfExist.split(' '); const updatedPackagesWithDocPages: Package[] = []; _.each(allUpdatedPackages, pkg => { - const nameWithoutPrefix = pkg.packageJson.name.replace('@0xproject/', ''); + const nameWithoutPrefix = pkg.packageJson.name.replace('@0x/', ''); if (_.includes(packagesWithDocPages, nameWithoutPrefix)) { updatedPackagesWithDocPages.push(pkg); } @@ -110,7 +110,7 @@ async function generateAndUploadDocJsonsAsync( shouldUploadDocs: boolean, ): Promise { for (const pkg of packagesWithDocs) { - const nameWithoutPrefix = pkg.packageJson.name.replace('@0xproject/', ''); + const nameWithoutPrefix = pkg.packageJson.name.replace('@0x/', ''); const docGenerateAndUploadUtils = new DocGenerateAndUploadUtils(nameWithoutPrefix, isStaging, shouldUploadDocs); await docGenerateAndUploadUtils.generateAndUploadDocsAsync(); } @@ -130,7 +130,7 @@ async function confirmDocPagesRenderAsync(packagesWithDocs: Package[]): Promise< _.each(packagesWithDocs, pkg => { const name = pkg.packageJson.name; - const nameWithoutPrefix = _.startsWith(name, NPM_NAMESPACE) ? name.split('@0xproject/')[1] : name; + const nameWithoutPrefix = _.startsWith(name, NPM_NAMESPACE) ? name.split('@0x/')[1] : name; const link = `${constants.stagingWebsite}/docs/${nameWithoutPrefix}`; // tslint:disable-next-line:no-floating-promises opn(link); diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 6090498e0..297eb3d50 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -15,7 +15,7 @@ const args = yargs 'Space-separated list of packages to generated release notes for. If not supplied, it does all `Lerna updated` packages.', type: 'string', }) - .example('$0 --isDryRun true --packages "0x.js @0xproject/web3-wrapper"', 'Full usage example').argv; + .example('$0 --isDryRun true --packages "0x.js @0x/web3-wrapper"', 'Full usage example').argv; (async () => { const isDryRun = args.isDryRun; diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index 459f70839..96875d0f9 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -12,7 +12,7 @@ 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. -const UNRUNNABLE_PACKAGES = ['@0xproject/abi-gen', '@0xproject/react-shared', '@0xproject/react-docs']; +const UNRUNNABLE_PACKAGES = ['@0x/abi-gen', '@0x/react-shared', '@0x/react-docs']; const mkdirpAsync = promisify(mkdirp); const rimrafAsync = promisify(rimraf); @@ -116,7 +116,7 @@ async function testInstallPackageAsync( 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'], + typeRoots: ['node_modules/@0x/typescript-typings/types', 'node_modules/@types'], module: 'commonjs', target: 'es5', lib: ['es2017', 'dom'], diff --git a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts index 547b65eeb..1a4294e9c 100644 --- a/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts +++ b/packages/monorepo-scripts/src/utils/doc_generate_and_upload_utils.ts @@ -402,7 +402,7 @@ export class DocGenerateAndUploadUtils { sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; return sanitizedExportPath; } - const monorepoPrefix = '@0xproject/'; + const monorepoPrefix = '@0x/'; if (_.startsWith(exportPath, monorepoPrefix)) { const sanitizedExportPath = exportPath.split(monorepoPrefix)[1]; sanitizedExportPathToExportPath[sanitizedExportPath] = exportPath; @@ -478,7 +478,7 @@ export class DocGenerateAndUploadUtils { }); }); - // @0xproject/types & ethereum-types are examples of packages where their index.ts exports types + // @0x/types & ethereum-types are examples of packages where their index.ts exports types // directly, meaning no internal paths will exist to follow. Other packages also have direct exports // in their index.ts, so we always add it to the source files passed to TypeDoc if (typeDocSourceIncludes.size === 0) { diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 0f3485de0..43c52ec2d 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -93,7 +93,7 @@ function adjustAssetPaths(assets: string[]): string[] { } function getReleaseNotesForPackage(packageName: string, version: string): string { - const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); + const packageNameWithoutNamespace = packageName.replace('@0x/', ''); const changelogJSONPath = path.join( constants.monorepoRootPath, 'packages', -- cgit v1.2.3 From 2735fb4fa6901dc528aea5f642512c161b842efd Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 18 Oct 2018 22:03:47 +1100 Subject: chore: change README.md from 0xproject to 0x --- packages/monorepo-scripts/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/README.md b/packages/monorepo-scripts/README.md index d979e27dc..0673098b5 100644 --- a/packages/monorepo-scripts/README.md +++ b/packages/monorepo-scripts/README.md @@ -47,13 +47,13 @@ yarn install To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: ```bash -PKG=@0xproject/monorepo-scripts yarn build +PKG=@0x/monorepo-scripts yarn build ``` Or continuously rebuild on change: ```bash -PKG=@0xproject/monorepo-scripts yarn watch +PKG=@0x/monorepo-scripts yarn watch ``` ### Clean -- cgit v1.2.3 From 8b62b350b1fed6a0d8827ca9ed5fcec3e78ae82f Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 18 Oct 2018 16:03:00 +0200 Subject: Publish - 0x.js@2.0.0 - @0x/abi-gen@1.0.14 - @0x/abi-gen-wrappers@1.0.1 - @0x/assert@1.0.14 - @0x/asset-buyer@2.1.0 - @0x/base-contract@3.0.2 - @0x/connect@3.0.2 - @0x/contract-addresses@1.0.1 - @0x/contract-artifacts@1.0.1 - @0x/contract-wrappers@3.0.0 - contracts@2.1.50 - @0x/dev-tools-pages@0.0.2 - @0x/dev-utils@1.0.13 - ethereum-types@1.1.1 - @0x/fill-scenarios@1.0.8 - @0x/instant@0.0.3 - @0x/json-schemas@2.0.0 - @0x/metacoin@0.0.24 - @0x/migrations@2.0.0 - @0x/monorepo-scripts@1.0.12 - @0x/order-utils@2.0.0 - @0x/order-watcher@2.2.0 - @0x/react-docs@1.0.14 - @0x/react-shared@1.0.17 - @0x/sol-compiler@1.1.8 - @0x/sol-cov@2.1.8 - @0x/sol-doc@1.0.3 - @0x/sol-resolver@1.0.15 - @0x/sra-spec@1.0.7 - @0x/subproviders@2.1.0 - @0x/testnet-faucets@1.0.52 - @0x/tslint-config@1.0.9 - @0x/types@1.2.0 - @0x/typescript-typings@3.0.3 - @0x/utils@2.0.3 - @0x/web3-wrapper@3.1.0 - @0x/website@0.0.55 --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 3a783af9b..ba5f9ca6a 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0x/monorepo-scripts", - "version": "1.0.11", + "version": "1.0.12", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From a7336d3c6594cdb2c19540d526b62ee05eda6cf5 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 18 Oct 2018 16:16:27 +0200 Subject: Don't attempt publishing if no packages need it --- packages/monorepo-scripts/src/publish.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index c1a6b9d7f..b7131e69e 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -35,6 +35,10 @@ async function confirmAsync(message: string): Promise { // Fetch public, updated Lerna packages const shouldIncludePrivate = true; const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + if (_.isEmpty(allUpdatedPackages)) { + utils.log('No packages need publishing'); + process.exit(0); + } const packagesWithDocs = getPackagesWithDocs(allUpdatedPackages); if (!configs.IS_LOCAL_PUBLISH) { -- cgit v1.2.3 From 3f2b6482c3e0abcc2b6dc1a3caef767c01a446b3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 19 Oct 2018 15:34:31 +0200 Subject: Fix the package versions in release notes --- packages/monorepo-scripts/src/prepublish_checks.ts | 2 +- packages/monorepo-scripts/src/publish.ts | 10 +++++----- packages/monorepo-scripts/src/publish_release_notes.ts | 2 +- .../monorepo-scripts/src/utils/github_release_utils.ts | 18 +++++++++--------- packages/monorepo-scripts/src/utils/utils.ts | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/prepublish_checks.ts b/packages/monorepo-scripts/src/prepublish_checks.ts index 683c26094..5f603ebc7 100644 --- a/packages/monorepo-scripts/src/prepublish_checks.ts +++ b/packages/monorepo-scripts/src/prepublish_checks.ts @@ -11,7 +11,7 @@ import { utils } from './utils/utils'; async function prepublishChecksAsync(): Promise { const shouldIncludePrivate = false; - const updatedPublicPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + const updatedPublicPackages = await utils.getPackagesToPublishAsync(shouldIncludePrivate); await checkCurrentVersionMatchesLatestPublishedNPMPackageAsync(updatedPublicPackages); await checkChangelogFormatAsync(updatedPublicPackages); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index b7131e69e..854a72b86 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -34,12 +34,12 @@ async function confirmAsync(message: string): Promise { (async () => { // Fetch public, updated Lerna packages const shouldIncludePrivate = true; - const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); - if (_.isEmpty(allUpdatedPackages)) { + const allPackagesToPublish = await utils.getPackagesToPublishAsync(shouldIncludePrivate); + if (_.isEmpty(allPackagesToPublish)) { utils.log('No packages need publishing'); process.exit(0); } - const packagesWithDocs = getPackagesWithDocs(allUpdatedPackages); + const packagesWithDocs = getPackagesWithDocs(allPackagesToPublish); if (!configs.IS_LOCAL_PUBLISH) { await confirmAsync( @@ -49,12 +49,12 @@ async function confirmAsync(message: string): Promise { } // Update CHANGELOGs - const updatedPublicPackages = _.filter(allUpdatedPackages, pkg => !pkg.packageJson.private); + const updatedPublicPackages = _.filter(allPackagesToPublish, pkg => !pkg.packageJson.private); const updatedPublicPackageNames = _.map(updatedPublicPackages, pkg => pkg.packageJson.name); utils.log(`Will update CHANGELOGs and publish: \n${updatedPublicPackageNames.join('\n')}\n`); const packageToNextVersion = await updateChangeLogsAsync(updatedPublicPackages); - const updatedPrivatePackages = _.filter(allUpdatedPackages, pkg => pkg.packageJson.private); + const updatedPrivatePackages = _.filter(allPackagesToPublish, pkg => pkg.packageJson.private); _.each(updatedPrivatePackages, pkg => { const currentVersion = pkg.packageJson.version; const packageName = pkg.packageJson.name; diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index 297eb3d50..d2082521c 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -22,7 +22,7 @@ const args = yargs let packages; if (_.isUndefined(args.packages)) { const shouldIncludePrivate = false; - packages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + packages = await utils.getPackagesToPublishAsync(shouldIncludePrivate); } else { const packageNames = args.packages.split(' '); packages = await utils.getPackagesByNameAsync(packageNames); diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 43c52ec2d..7434d397e 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -12,7 +12,7 @@ import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); // tslint:disable-next-line:completed-docs -export async function publishReleaseNotesAsync(updatedPublishPackages: Package[], isDryRun: boolean): Promise { +export async function publishReleaseNotesAsync(packagesToPublish: Package[], isDryRun: boolean): Promise { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); const latestGitCommit = result.stdout; @@ -40,12 +40,8 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] let assets: string[] = []; let aggregateNotes = ''; - _.each(updatedPublishPackages, pkg => { - const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); - if (_.isEmpty(notes)) { - return; // don't include it - } - aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; + _.each(packagesToPublish, pkg => { + aggregateNotes += getReleaseNotesForPackage(pkg.packageJson.name); const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); if (!_.isUndefined(packageAssets)) { @@ -92,7 +88,7 @@ function adjustAssetPaths(assets: string[]): string[] { return finalAssets; } -function getReleaseNotesForPackage(packageName: string, version: string): string { +function getReleaseNotesForPackage(packageName: string): string { const packageNameWithoutNamespace = packageName.replace('@0x/', ''); const changelogJSONPath = path.join( constants.monorepoRootPath, @@ -115,5 +111,9 @@ function getReleaseNotesForPackage(packageName: string, version: string): string } notes += `\n`; }); - return notes; + if (_.isEmpty(notes)) { + return ''; // don't include it + } + const releaseNotesSection = `### ${packageName}@${latestLog.version}\n${notes}\n\n`; + return releaseNotesSection; } diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 5e2e877c7..44ff971e8 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -61,7 +61,7 @@ export const utils = { }); return updatedPackages; }, - async getUpdatedPackagesAsync(shouldIncludePrivate: boolean): Promise { + async getPackagesToPublishAsync(shouldIncludePrivate: boolean): Promise { const updatedPublicPackages = await utils.getLernaUpdatedPackagesAsync(shouldIncludePrivate); const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); -- cgit v1.2.3 From dcd428a4a299de0daf6bbfb8e8a7c15685b673cf Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Wed, 17 Oct 2018 09:54:41 -0700 Subject: feat(monorepo-scripts): add ForwarderWrapperError to IGNORED_EXCESSIVE_TYPES in docGenConfigs --- packages/monorepo-scripts/CHANGELOG.json | 4 ++++ packages/monorepo-scripts/src/doc_gen_configs.ts | 1 + 2 files changed, 5 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json index 4797fd929..170a97a33 100644 --- a/packages/monorepo-scripts/CHANGELOG.json +++ b/packages/monorepo-scripts/CHANGELOG.json @@ -9,6 +9,10 @@ { "note": "Add AssetBuyerError to the IGNORED_EXCESSIVE_TYPES array", "pr": 1139 + }, + { + "note": "Add ForwarderError to the IGNORED_EXCESSIVE_TYPES array", + "pr": 1147 } ] }, diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 0aaf5a6a5..7a14f8664 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -56,6 +56,7 @@ export const docGenConfigs: DocGenConfigs = { 'ContractWrappersError', 'OrderError', 'AssetBuyerError', + 'ForwarderWrapperError', ], // Some libraries only export types. In those cases, we cannot check if the exported types are part of the // "exported public interface". Thus we add them here and skip those checks. -- cgit v1.2.3 From 2c04ee3f5e4438f9ae51944e7ea6bd6b501317a7 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 23 Oct 2018 18:30:11 -0700 Subject: chore: Add --format stylish to tslint --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index ba5f9ca6a..a83f90516 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -11,7 +11,7 @@ "scripts": { "build": "tsc -b", "build:ci": "yarn build", - "lint": "tslint --project .", + "lint": "tslint --format stylish --project .", "clean": "shx rm -rf lib", "test:publish": "run-s build script:publish", "find_unused_deps": "run-s build script:find_unused_deps", -- cgit v1.2.3