Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: re-allow monocdk deep imports #17791

Merged
merged 7 commits into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/monocdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
}
},
"ubergen": {
"explicitExports": false,
"libRoot": "lib",
"deprecatedPackages": [
"@aws-cdk/aws-dynamodb-global",
"@aws-cdk/cdk-assets-schema"
Expand Down
61 changes: 47 additions & 14 deletions tools/@aws-cdk/ubergen/bin/ubergen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,23 @@ import * as fs from 'fs-extra';
// The directory where our 'package.json' lives
const MONOPACKAGE_ROOT = process.cwd();

// The directory where we're going to collect all the libraries. Currently
// purposely the same as the monopackage root so that our two import styles
// resolve to the same files.
const LIB_ROOT = MONOPACKAGE_ROOT;

const ROOT_PATH = findWorkspacePath();
const UBER_PACKAGE_JSON_PATH = path.join(MONOPACKAGE_ROOT, 'package.json');

async function main() {
console.log(`🌴 workspace root path is: ${ROOT_PATH}`);
const uberPackageJson = await fs.readJson(UBER_PACKAGE_JSON_PATH);
const uberPackageJson = await fs.readJson(UBER_PACKAGE_JSON_PATH) as PackageJson;
const libraries = await findLibrariesToPackage(uberPackageJson);
await verifyDependencies(uberPackageJson, libraries);
await prepareSourceFiles(libraries, uberPackageJson);
await combineRosettaFixtures(libraries, uberPackageJson);

// if explicitExports is set to `false`, remove the "exports" section from package.json
const explicitExports = uberPackageJson.ubergen?.explicitExports ?? true;
if (!explicitExports) {
delete uberPackageJson.exports;
}

// Rewrite package.json (exports will have changed)
await fs.writeJson(UBER_PACKAGE_JSON_PATH, uberPackageJson, { spaces: 2 });
}
Expand Down Expand Up @@ -79,6 +80,21 @@ interface PackageJson {
readonly ubergen?: {
readonly deprecatedPackages?: readonly string[];
readonly excludeExperimentalModules?: boolean;

/**
* The directory where we're going to collect all the libraries.
*
* @default - root of the ubergen package
*/
readonly libRoot?: string;

/**
* Adds an `exports` section to the ubergen package.json file to ensure that
* consumers won't be able to accidentally import a private file.
*
* @default true
*/
readonly explicitExports?: boolean;
};
exports?: Record<string, string>;
}
Expand Down Expand Up @@ -236,9 +252,11 @@ async function prepareSourceFiles(libraries: readonly LibraryReference[], packag
console.log('\t 👩🏻‍🔬 \'excludeExperimentalModules\' enabled. Regenerating all experimental modules as L1s using cfn2ts...');
}

const libRoot = resolveLibRoot(packageJson);

// Should not remove collection directory if we're currently in it. The OS would be unhappy.
if (LIB_ROOT !== process.cwd()) {
await fs.remove(LIB_ROOT);
if (libRoot !== process.cwd()) {
await fs.remove(libRoot);
}

// Control 'exports' field of the 'package.json'. This will control what kind of 'import' statements are
Expand All @@ -257,7 +275,7 @@ async function prepareSourceFiles(libraries: readonly LibraryReference[], packag

const indexStatements = new Array<string>();
for (const library of libraries) {
const libDir = path.join(LIB_ROOT, library.shortName);
const libDir = path.join(libRoot, library.shortName);
const copied = await transformPackage(library, packageJson, libDir, libraries);

if (!copied) {
Expand All @@ -271,7 +289,7 @@ async function prepareSourceFiles(libraries: readonly LibraryReference[], packag
}
}

await fs.writeFile(path.join(LIB_ROOT, 'index.ts'), indexStatements.join('\n'), { encoding: 'utf8' });
await fs.writeFile(path.join(libRoot, 'index.ts'), indexStatements.join('\n'), { encoding: 'utf8' });

console.log('\t🍺 Success!');
}
Expand Down Expand Up @@ -414,6 +432,7 @@ function transformTargets(monoConfig: PackageJson['jsii']['targets'], targets: P
}

async function copyOrTransformFiles(from: string, to: string, libraries: readonly LibraryReference[], uberPackageJson: PackageJson) {
const libRoot = resolveLibRoot(uberPackageJson);
const promises = (await fs.readdir(from)).map(async name => {
if (shouldIgnoreFile(name)) { return; }

Expand All @@ -436,7 +455,7 @@ async function copyOrTransformFiles(from: string, to: string, libraries: readonl
if (name.endsWith('.ts')) {
return fs.writeFile(
destination,
await rewriteLibraryImports(source, to, libraries),
await rewriteLibraryImports(source, to, libRoot, libraries),
{ encoding: 'utf8' },
);
} else if (name === 'cfn-types-2-classes.json') {
Expand Down Expand Up @@ -483,7 +502,7 @@ async function rewriteReadmeImports(fromFile: string, libName: string): Promise<
/**
* Rewrites imports in libaries, using the relative path (i.e. '../../assertions').
*/
async function rewriteLibraryImports(fromFile: string, targetDir: string, libraries: readonly LibraryReference[]): Promise<string> {
async function rewriteLibraryImports(fromFile: string, targetDir: string, libRoot: string, libraries: readonly LibraryReference[]): Promise<string> {
const source = await fs.readFile(fromFile, { encoding: 'utf8' });
return awsCdkMigration.rewriteImports(source, relativeImport);

Expand All @@ -496,8 +515,8 @@ async function rewriteLibraryImports(fromFile: string, targetDir: string, librar
if (sourceLibrary == null) { return undefined; }

const importedFile = modulePath === sourceLibrary.packageJson.name
? path.join(LIB_ROOT, sourceLibrary.shortName)
: path.join(LIB_ROOT, sourceLibrary.shortName, modulePath.substr(sourceLibrary.packageJson.name.length + 1));
? path.join(libRoot, sourceLibrary.shortName)
: path.join(libRoot, sourceLibrary.shortName, modulePath.substr(sourceLibrary.packageJson.name.length + 1));

return path.relative(targetDir, importedFile);
}
Expand Down Expand Up @@ -545,4 +564,18 @@ function sortObject<T>(obj: Record<string, T>): Record<string, T> {
*/
function unixPath(x: string) {
return x.replace(/\\/g, '/');
}

/**
* Resolves the directory where we're going to collect all the libraries.
*
* By default, this is purposely the same as the monopackage root so that our
* two import styles resolve to the same files but it can be overridden by
* seeting `ubergen.libRoot` in the package.json of the uber package.
*
* @param uberPackageJson package.json contents of the uber package
* @returns The directory where we should collect all the libraries.
*/
function resolveLibRoot(uberPackageJson: PackageJson): string {
return uberPackageJson.ubergen?.libRoot ?? MONOPACKAGE_ROOT;
eladb marked this conversation as resolved.
Show resolved Hide resolved
}