diff --git a/pack.sh b/pack.sh index 128d8e3fd8a90..b85c92f3e68a5 100755 --- a/pack.sh +++ b/pack.sh @@ -63,19 +63,6 @@ for dir in $(find packages -name dist | grep -v node_modules | grep -v run-wrapp rsync -a $dir/ ${distdir}/ done -# Make sure that none of the NPM tarballs have stray `.ts` files in them. -# This is necessary because the presence of .ts files without a matching tsconfig will -# make `ts-node` fail to load the files with a "Cannot use import statement outside a module" error. -for tarball in ${distdir}/js/*.tgz; do - # Ignore init-templates, we purposely ship .ts files in there. - ts_files=$(tar tzf ${tarball} | (set +e; grep '\.ts$' | grep -v '\.d\.ts$' | grep -v init-templates)) - if [[ "$ts_files" != "" ]]; then - echo "Found TypeScript source files in $tarball. This will confuse ts-node:" >&2 - echo "$ts_files" >&2 - exit 1 - fi -done - # Record the dependency order of NPM packages into a file # (This file will be opportunistically used during publishing) # diff --git a/package.json b/package.json index d3c9a5569ce0c..8420edf113ed3 100644 --- a/package.json +++ b/package.json @@ -51,9 +51,6 @@ "nohoist": [ "**/jszip", "**/jszip/**", - "@aws-cdk/aws-codebuild/@aws-cdk/yaml-cfn", - "@aws-cdk/aws-codebuild/@aws-cdk/yaml-cfn/yaml", - "@aws-cdk/aws-codebuild/@aws-cdk/yaml-cfn/yaml/**", "@aws-cdk/aws-codepipeline-actions/case", "@aws-cdk/aws-codepipeline-actions/case/**", "@aws-cdk/aws-cognito/punycode", @@ -66,9 +63,6 @@ "@aws-cdk/cloud-assembly-schema/jsonschema/**", "@aws-cdk/cloud-assembly-schema/semver", "@aws-cdk/cloud-assembly-schema/semver/**", - "@aws-cdk/cloudformation-include/@aws-cdk/yaml-cfn", - "@aws-cdk/cloudformation-include/@aws-cdk/yaml-cfn/yaml", - "@aws-cdk/cloudformation-include/@aws-cdk/yaml-cfn/yaml/**", "@aws-cdk/core/@balena/dockerignore", "@aws-cdk/core/@balena/dockerignore/**", "@aws-cdk/core/fs-extra", @@ -81,9 +75,6 @@ "@aws-cdk/cx-api/semver/**", "@aws-cdk/yaml-cfn/yaml", "@aws-cdk/yaml-cfn/yaml/**", - "aws-cdk-lib/@aws-cdk/yaml-cfn", - "aws-cdk-lib/@aws-cdk/yaml-cfn/yaml", - "aws-cdk-lib/@aws-cdk/yaml-cfn/yaml/**", "aws-cdk-lib/@balena/dockerignore", "aws-cdk-lib/@balena/dockerignore/**", "aws-cdk-lib/case", @@ -102,9 +93,6 @@ "aws-cdk-lib/semver/**", "aws-cdk-lib/yaml", "aws-cdk-lib/yaml/**", - "monocdk/@aws-cdk/yaml-cfn", - "monocdk/@aws-cdk/yaml-cfn/yaml", - "monocdk/@aws-cdk/yaml-cfn/yaml/**", "monocdk/@balena/dockerignore", "monocdk/@balena/dockerignore/**", "monocdk/case", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index e07695b75ba31..e5a9a34ecd807 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -49,7 +49,6 @@ "build+test": "yarn build && yarn test", "compat": "cdk-compat", "gen": "cfn2ts", - "postpack": "cdk-postpack", "rosetta:extract": "yarn --silent jsii-rosetta extract" }, "cdk-build": { @@ -104,9 +103,6 @@ "@aws-cdk/yaml-cfn": "0.0.0", "constructs": "^3.3.69" }, - "bundledDependencies": [ - "@aws-cdk/yaml-cfn" - ], "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { "@aws-cdk/aws-cloudwatch": "0.0.0", @@ -123,6 +119,7 @@ "@aws-cdk/aws-secretsmanager": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/region-info": "0.0.0", + "@aws-cdk/yaml-cfn": "0.0.0", "constructs": "^3.3.69" }, "engines": { diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index ac7261b681d34..b9b82e67f55a3 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -47,8 +47,7 @@ "build+test": "yarn build && yarn test", "build+test+package": "yarn build+test && yarn package", "compat": "cdk-compat", - "rosetta:extract": "yarn --silent jsii-rosetta extract", - "postpack": "cdk-postpack" + "rosetta:extract": "yarn --silent jsii-rosetta extract" }, "cdk-build": { "pre": [ @@ -364,6 +363,7 @@ "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", "@aws-cdk/core": "0.0.0", + "@aws-cdk/yaml-cfn": "0.0.0", "constructs": "^3.3.69" }, "devDependencies": { @@ -375,9 +375,6 @@ "pkglint": "0.0.0", "ts-jest": "^26.5.4" }, - "bundledDependencies": [ - "@aws-cdk/yaml-cfn" - ], "keywords": [ "aws", "cdk", diff --git a/packages/@aws-cdk/yaml-cfn/.gitignore b/packages/@aws-cdk/yaml-cfn/.gitignore index 8b9c845e5d12a..bb785cfb74f08 100644 --- a/packages/@aws-cdk/yaml-cfn/.gitignore +++ b/packages/@aws-cdk/yaml-cfn/.gitignore @@ -3,6 +3,7 @@ *.d.ts node_modules dist +tsconfig.json .jsii .LAST_BUILD @@ -14,4 +15,4 @@ nyc.config.js !.eslintrc.js !jest.config.js -junit.xml +junit.xml \ No newline at end of file diff --git a/packages/@aws-cdk/yaml-cfn/package.json b/packages/@aws-cdk/yaml-cfn/package.json index a50d4ab10eece..f10beb171366c 100644 --- a/packages/@aws-cdk/yaml-cfn/package.json +++ b/packages/@aws-cdk/yaml-cfn/package.json @@ -23,6 +23,32 @@ "cloudformation", "yaml" ], + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.amazon.awscdk.yaml.cfn", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "cdk-yaml-cfn" + } + }, + "dotnet": { + "namespace": "Amazon.CDK.Yaml.Cfn", + "packageId": "Amazon.CDK.Yaml.Cfn", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "python": { + "distName": "aws-cdk.yaml-cfn", + "module": "aws_cdk.yaml_cfn", + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ] + } + }, + "projectReferences": true + }, "scripts": { "build": "cdk-build", "watch": "cdk-watch", diff --git a/packages/@aws-cdk/yaml-cfn/tsconfig.json b/packages/@aws-cdk/yaml-cfn/tsconfig.json deleted file mode 100644 index 5e75173fa8734..0000000000000 --- a/packages/@aws-cdk/yaml-cfn/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "target":"ES2018", - "module": "commonjs", - "lib": ["es2016", "es2017.object", "es2017.string"], - "declaration": true, - "composite": true, - "strict": true, - "noImplicitAny": true, - "strictNullChecks": true, - "noImplicitThis": true, - "alwaysStrict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": false, - "inlineSourceMap": true, - "inlineSources": true, - "experimentalDecorators": true, - "strictPropertyInitialization":false - }, - "include": ["**/*.ts" ], - "exclude": ["node_modules"] -} diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 9c3057ec1e728..cef21953bf34a 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -23,8 +23,7 @@ "build+test+package": "yarn build+test && yarn package", "watch": "cdk-watch", "compat": "cdk-compat", - "rosetta:extract": "yarn --silent jsii-rosetta extract", - "postpack": "cdk-postpack" + "rosetta:extract": "yarn --silent jsii-rosetta extract" }, "awslint": { "exclude": [ @@ -83,7 +82,6 @@ }, "license": "Apache-2.0", "bundledDependencies": [ - "@aws-cdk/yaml-cfn", "@balena/dockerignore", "case", "fs-extra", @@ -95,7 +93,6 @@ "yaml" ], "dependencies": { - "@aws-cdk/yaml-cfn": "0.0.0", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", "fs-extra": "^9.1.0", diff --git a/packages/awslint/.npmignore b/packages/awslint/.npmignore index d3305e57c78c2..7cb354bd2b155 100644 --- a/packages/awslint/.npmignore +++ b/packages/awslint/.npmignore @@ -1,5 +1,4 @@ -*.ts -!*.d.ts + dist .LAST_PACKAGE .LAST_BUILD @@ -10,4 +9,4 @@ dist tsconfig.json .eslintrc.js junit.xml -test/ +test/ \ No newline at end of file diff --git a/packages/decdk/test/schema.test.ts b/packages/decdk/test/schema.test.ts index 84888d94b365b..7b097dcc9fcbe 100644 --- a/packages/decdk/test/schema.test.ts +++ b/packages/decdk/test/schema.test.ts @@ -79,7 +79,7 @@ test('schemaForInterface: interface with primitives', async () => { * are propagated outwards. */ function spawn(command: string, options: SpawnOptions | undefined) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { const cp = spawnAsync(command, [], { stdio: 'inherit', ...options }); cp.on('error', reject); diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index c2fa7b0bbbf5a..ce9057690ff00 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -22,8 +22,7 @@ "build+test+package": "yarn build+test && yarn package", "watch": "cdk-watch", "compat": "cdk-compat", - "rosetta:extract": "yarn --silent jsii-rosetta extract", - "postpack": "cdk-postpack" + "rosetta:extract": "yarn --silent jsii-rosetta extract" }, "awslint": { "exclude": [ @@ -88,7 +87,6 @@ }, "license": "Apache-2.0", "bundledDependencies": [ - "@aws-cdk/yaml-cfn", "@balena/dockerignore", "case", "fs-extra", @@ -100,7 +98,6 @@ "yaml" ], "dependencies": { - "@aws-cdk/yaml-cfn": "0.0.0", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", "fs-extra": "^9.1.0", diff --git a/tools/cdk-build-tools/bin/cdk-postpack b/tools/cdk-build-tools/bin/cdk-postpack deleted file mode 100755 index 0805422de11c8..0000000000000 --- a/tools/cdk-build-tools/bin/cdk-postpack +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -require('./cdk-postpack.js'); diff --git a/tools/cdk-build-tools/bin/cdk-postpack.ts b/tools/cdk-build-tools/bin/cdk-postpack.ts deleted file mode 100644 index 02b486b290512..0000000000000 --- a/tools/cdk-build-tools/bin/cdk-postpack.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { promises as fs, createReadStream, createWriteStream } from 'fs'; -import * as path from 'path'; -import * as zlib from 'zlib'; -import * as npmPacklist from 'npm-packlist'; -import * as tar from 'tar-stream'; - -/** - * This script has literally ONE job: - * - * To massage the tarball that `npm pack` produces if we have bundled monorepo dependencies. - * - * The reason is that `npm pack` will SKIP the `.npmignore` files from - * `bundledDependencies`[0]. Not a problem for dependencies that were themselves - * downloaded from NPM, but definitely a problem for dependencies that are symlinked - * to source locations (such as those by `npm link` or by a monorepo setup). - * - * This leads to all the `.ts` files from the bundledDependency being included, - * which in turn leads `ts-node` to read those files (in preference over `.js` - * files with the same name), and then subsequently getting confused because - * there is no `tsconfig.json` file that tells it how to compile them them (and - * the defaults don't work out). - * - * (Shitty) solution: postprocess the tarball that `npm pack` produces, to - * remove the files that should have been excluded by NPM in the first place. - * - * [0]: https://github.com/npm/cli/issues/718 - */ -async function main() { - const tarball = await findTarballFile(); - const rewritten = `${tarball}.tmp`; - - await transformTarball(tarball, rewritten); - - await fs.rename(rewritten, tarball); -} - -async function transformTarball(oldPath: string, newPath: string) { - const cache = new NpmListCache(); - - const { input, output } = createTarballFilterStream(async (headers) => { - // Paths in a NPM tarball always start with 'package/', strip it off to get to a real relative path - const relativePath = headers.name.replace(/^package\//, ''); - - // We only have to care about files that are in bundled dependencies (which means their - // path starts with 'node_modules/') - if (!relativePath.startsWith('node_modules/')) { return true; } - - // Resolve symlinks. Only do special things if the symlink does NOT have /node_modules/ in the path, which - // is when we're dealing with a symlinked package that NPM will have misprocessed. - // Otherwise just include the file. - const absPath = await fs.realpath(relativePath); - if (absPath.includes('/node_modules/')) { return true; } - - return cache.shouldPublish(absPath); - }); - - await new Promise((ok, ko) => { - // Thanks Node. This is a really thoughtful API and really much better! [1] - createReadStream(oldPath) - .on('error', () => ko()) - .pipe(zlib.createGunzip()) - .on('error', () => ko()) - .pipe(input) - .on('error', () => ko()); - - const outputStream = createWriteStream(newPath); - - output - .on('error', () => ko()) - .pipe(zlib.createGzip()) - .on('error', () => ko()) - .pipe(outputStream) - .on('error', () => ko()); - - outputStream.on('close', () => ok()); - }); -} - -/** - * Create a stream that will retain/remove entries from a tarball based on a predicate - * - * Returns the input and output ends of the stream. - */ -function createTarballFilterStream(include: (headers: tar.Headers) => Promise) { - const input = tar.extract(); - const output = tar.pack(); - - input.on('entry', (headers, stream, next) => { - include(headers).then(doInclude => { - if (doInclude) { - // Pipe body to output - stream.pipe(output.entry(headers, next)); - } else { - // eslint-disable-next-line no-console - console.error(`[cdk-postpack] Belatedly npmignored: ${headers.name}`); - // Consume the stream without writing it anywhere - stream.on('end', next); - stream.resume(); - } - }).catch(e => { - input.destroy(e); - output.destroy(e); - }); - }); - - input.on('finish', () => { - output.finalize(); - }); - - return { input, output }; -} - -/** - * Expect one .tgz file in the current directory and return its name - */ -async function findTarballFile() { - const entries = await fs.readdir('.'); - const tgzs = entries.filter(e => e.endsWith('.tgz')); - if (tgzs.length !== 1) { - throw new Error(`Expecting extactly one .tgz file, got: ${tgzs}`); - } - return tgzs[0]; -} - -class NpmListCache { - private listCache: Record = {}; - - public async shouldPublish(absPath: string) { - const pjDir = path.dirname(await findUp('package.json', path.dirname(absPath))); - const files = await this.obtainNpmPackList(pjDir); - - const relativePath = path.relative(pjDir, absPath); - return files.includes(relativePath); - } - - /** - * Use 'npm-packlist' (official NPM package) to get the list of files that NPM would publish from the given directory - * - * This will take into account the .npmignore files. - */ - private async obtainNpmPackList(dir: string) { - if (this.listCache[dir]) { return this.listCache[dir]; } - - const files = await npmPacklist({ path: dir }); - this.listCache[dir] = files; - return files; - } -} - -async function findUp(fileName: string, start: string) { - let dir = start; - while (!await fileExists(path.join(dir, fileName))) { - const parent = path.dirname(dir); - if (parent === dir) { - throw new Error(`No ${fileName} found upwards from ${start}`); - } - dir = parent; - } - return path.join(dir, fileName); -} - -async function fileExists(fullPath: string): Promise { - try { - await fs.stat(fullPath); - return true; - } catch (e) { - if (e.code === 'ENOENT' || e.code === 'ENOTDIR') { return false; } - throw e; - } -} - -main().catch(e => { - // eslint-disable-next-line no-console - console.log('Error', e); - process.exitCode = 1; -}); - - -// [1] /s \ No newline at end of file diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 3d896f5b38229..dd6523d47e2df 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -16,8 +16,7 @@ "cdk-test": "bin/cdk-test", "cdk-package": "bin/cdk-package", "cdk-awslint": "bin/cdk-awslint", - "cdk-lint": "bin/cdk-lint", - "cdk-postpack": "bin/cdk-postpack" + "cdk-lint": "bin/cdk-lint" }, "scripts": { "build": "tsc -b && chmod +x bin/cdk-build && chmod +x bin/cdk-test && chmod +x bin/cdk-watch && chmod +x bin/cdk-awslint && chmod +x bin/cdk-lint && pkglint && eslint . --ext=.ts", @@ -36,9 +35,7 @@ "devDependencies": { "@types/fs-extra": "^8.1.1", "@types/jest": "^26.0.22", - "@types/tar-stream": "^2.2.0", "@types/yargs": "^15.0.13", - "@types/npm-packlist": "^1.1.1", "pkglint": "0.0.0" }, "dependencies": { @@ -58,10 +55,8 @@ "jsii-pacmak": "^1.27.0", "markdownlint-cli": "^0.27.1", "nodeunit": "^0.11.3", - "npm-packlist": "2.1.5", "nyc": "^15.1.0", "semver": "^7.3.5", - "tar-stream": "^2.2.0", "ts-jest": "^26.5.4", "typescript": "~3.9.9", "yargs": "^16.2.0", diff --git a/tools/nodeunit-shim/index.ts b/tools/nodeunit-shim/index.ts index 1c4ee174ff229..8ba50bedefefd 100644 --- a/tools/nodeunit-shim/index.ts +++ b/tools/nodeunit-shim/index.ts @@ -81,7 +81,7 @@ export function nodeunitShim(exports: Record) { }); } else { // It's a test - test(testName, () => new Promise(ok => { + test(testName, () => new Promise(ok => { testObj(new Test(ok)); })); } diff --git a/tools/pkglint/bin/pkglint.ts b/tools/pkglint/bin/pkglint.ts index 31cf7f5d2c74d..0b5cd61ef1649 100644 --- a/tools/pkglint/bin/pkglint.ts +++ b/tools/pkglint/bin/pkglint.ts @@ -24,16 +24,8 @@ async function main(): Promise { const pkgs = findPackageJsons(argv.directory as string); - for (const rule of rules) { - for (const pkg of pkgs.filter(pkg => pkg.shouldApply(rule))) { - rule.prepare(pkg); - } - } - for (const rule of rules) { - for (const pkg of pkgs.filter(pkg => pkg.shouldApply(rule))) { - await rule.validate(pkg); - } - } + rules.forEach(rule => pkgs.filter(pkg => pkg.shouldApply(rule)).forEach(pkg => rule.prepare(pkg))); + rules.forEach(rule => pkgs.filter(pkg => pkg.shouldApply(rule)).forEach(pkg => rule.validate(pkg))); if (argv.fix) { pkgs.forEach(pkg => pkg.applyFixes()); diff --git a/tools/pkglint/lib/packagejson.ts b/tools/pkglint/lib/packagejson.ts index 7a7375fbe6fab..a59e8f1c6e307 100644 --- a/tools/pkglint/lib/packagejson.ts +++ b/tools/pkglint/lib/packagejson.ts @@ -361,5 +361,5 @@ export abstract class ValidationRule { /** * Will be executed for every package definition once, should mutate the package object */ - public abstract validate(pkg: PackageJson): void | Promise; + public abstract validate(pkg: PackageJson): void; } diff --git a/tools/pkglint/lib/rules.ts b/tools/pkglint/lib/rules.ts index 6b32110ad99d6..f7929a353035a 100644 --- a/tools/pkglint/lib/rules.ts +++ b/tools/pkglint/lib/rules.ts @@ -1,7 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; import * as caseUtils from 'case'; -import * as fse from 'fs-extra'; import * as glob from 'glob'; import * as semver from 'semver'; import { LICENSE, NOTICE } from './licensing'; @@ -12,7 +11,6 @@ import { fileShouldBe, fileShouldBeginWith, fileShouldContain, fileShouldNotContain, findInnerPackages, - findPackageDir, monoRepoRoot, } from './util'; @@ -1373,42 +1371,25 @@ export class FastFailingBuildScripts extends ValidationRule { } } -/** - * For every bundled dependency, we need to make sure that package and all of its transitive dependencies are nohoisted - * - * Bundling literally works by including `/node_modules/` into - * the tarball when `npm pack` is run, and if that directory does not exist at - * that exact location (because it has been hoisted) then NPM shrugs its - * shoulders and the dependency will be missing from the distribution. - * - * -- - * - * We also must not forget to nohoist transitive dependencies. Strictly - * speaking, we need to only hoist transitive *runtime* dependencies (`dependencies`, not - * `devDependencies`). - * - * For 3rd party deps, there is no difference and we short-circuit by adding a - * catch-all glob (`/node_modules//**`), but for in-repo bundled - * dependencies, we DO need the `devDependencies` installed as per normal and - * only the transitive runtime dependencies nohoisted (recursively). - */ export class YarnNohoistBundledDependencies extends ValidationRule { public readonly name = 'yarn/nohoist-bundled-dependencies'; - public async validate(pkg: PackageJson) { + public validate(pkg: PackageJson) { const bundled: string[] = pkg.json.bundleDependencies || pkg.json.bundledDependencies || []; + if (bundled.length === 0) { return; } const repoPackageJson = path.resolve(__dirname, '../../../package.json'); - const nohoist = new Set(require(repoPackageJson).workspaces.nohoist); // eslint-disable-line @typescript-eslint/no-require-imports - const expectedNoHoistEntries = new Array(); + const nohoist: string[] = require(repoPackageJson).workspaces.nohoist; // eslint-disable-line @typescript-eslint/no-require-imports + const missing = new Array(); for (const dep of bundled) { - await noHoistDependency(pkg.packageName, dep, pkg.packageRoot); + for (const entry of [`${pkg.packageName}/${dep}`, `${pkg.packageName}/${dep}/**`]) { + if (nohoist.indexOf(entry) >= 0) { continue; } + missing.push(entry); + } } - const missing = expectedNoHoistEntries.filter(entry => !nohoist.has(entry)); - if (missing.length > 0) { pkg.report({ ruleName: this.name, @@ -1420,43 +1401,6 @@ export class YarnNohoistBundledDependencies extends ValidationRule { }, }); } - - async function noHoistDependency(parentPackageHierarchy: string, depName: string, parentPackageDir: string) { - expectedNoHoistEntries.push(`${parentPackageHierarchy}/${depName}`); - - const dependencyDir = await findPackageDir(depName, parentPackageDir); - if (!isMonoRepoPackageDir(dependencyDir)) { - // Not one of ours, so we can just ignore everything underneath as well - expectedNoHoistEntries.push(`${parentPackageHierarchy}/${depName}/**`); - return; - } - - // A monorepo package, recurse into dependencies (but not devDependencies) - const packageJson = await fse.readJson(path.join(dependencyDir, 'package.json')); - for (const dep of Object.keys(packageJson.dependencies ?? {})) { - await noHoistDependency(`${parentPackageHierarchy}/${depName}`, dep, dependencyDir); - } - } - } -} - -/** - * If this package has bundled dependencies that come from the monorepo, it MUST use `cdk-postpack` as postpack script - */ -export class BundledMonorepoDependencies extends ValidationRule { - public readonly name = 'monorepo/monorepo-bundled-dependencies'; - - public async validate(pkg: PackageJson) { - const bundled: string[] = pkg.json.bundleDependencies || pkg.json.bundledDependencies || []; - - const bundledDepsMonoRepo = await Promise.all(bundled.map(async (dep) => { - const dependencyDir = await findPackageDir(dep, pkg.packageRoot); - return isMonoRepoPackageDir(dependencyDir); - })); - - if (bundledDepsMonoRepo.some(x => x)) { - expectJSON(this.name, pkg, 'scripts.postpack', 'cdk-postpack'); - } } } @@ -1726,14 +1670,3 @@ function cdkMajorVersion() { const releaseJson = require(`${__dirname}/../../../release.json`); return releaseJson.majorVersion as number; } - -/** - * Whether this is a package in the monorepo or not - * - * We're going to be cheeky and not do too much analysis, and say that - * a package that has `/node_modules/` in the directory name is NOT in the - * monorepo, otherwise it is. - */ -function isMonoRepoPackageDir(packageDir: string) { - return path.resolve(packageDir).indexOf(`${path.sep}node_modules${path.sep}`) === -1; -} \ No newline at end of file diff --git a/tools/pkglint/lib/util.ts b/tools/pkglint/lib/util.ts index fe56512113ec2..10b4415a6c3ca 100644 --- a/tools/pkglint/lib/util.ts +++ b/tools/pkglint/lib/util.ts @@ -190,39 +190,3 @@ export function* findInnerPackages(dir: string): IterableIterator { yield* findInnerPackages(path.join(dir, fname)); } } - -/** - * Find package directory - * - * Do this by walking upwards in the directory tree until we find - * `/node_modules//package.json`. - * - * ------- - * - * Things that we tried but don't work: - * - * 1. require.resolve(`${depName}/package.json`, { paths: [rootDir] }); - * - * Breaks with ES Modules if `package.json` has not been exported, which is - * being enforced starting Node12. - * - * 2. findPackageJsonUpwardFrom(require.resolve(depName, { paths: [rootDir] })) - * - * Breaks if a built-in NodeJS package name conflicts with an NPM package name - * (in Node15 `string_decoder` is introduced...) - */ -export async function findPackageDir(depName: string, rootDir: string) { - let prevDir; - let dir = rootDir; - while (dir !== prevDir) { - const candidateDir = path.join(dir, 'node_modules', depName); - if (await new Promise(ok => fs.exists(path.join(candidateDir, 'package.json'), ok))) { - return new Promise((ok, ko) => fs.realpath(candidateDir, (err, result) => err ? ko(err) : ok(result))); - } - - prevDir = dir; - dir = path.dirname(dir); // dirname('/') -> '/', dirname('c:\\') -> 'c:\\' - } - - throw new Error(`Did not find '${depName}' upwards of '${rootDir}'`); -} \ No newline at end of file