-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rosetta): Rosetta manages dependencies automatically (#3269)
It's quite an annoying bother and pretty brittle to have to set up a full dependency directory to compile examples in. In CDK, we use the directory of the `decdk` package to do this, because we have external knowledge that all packages will be symlinked into this directory. That mechanism is brittle and revolves around having outside knowledge. Instead, make Rosetta manage the dependency closure itself, when user declare `exampleDependencies` in `package.json`: ``` { "jsiiRosetta": { "exampleDependencies": { "@some-other/package": "^1.2.3", "@yet-another/package": "*", } } } ``` It is not necessary to redeclare any of the `dependencies` and `peerDependencies` already in `package.json`: those are automatically included. --- By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license]. [Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
- Loading branch information
Showing
26 changed files
with
755 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import * as fs from 'fs-extra'; | ||
import * as path from 'path'; | ||
|
||
/** | ||
* Find the directory that contains a given dependency, identified by its 'package.json', from a starting search directory | ||
* | ||
* (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all | ||
* 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) | ||
*/ | ||
export async function findDependencyDirectory(dependencyName: string, searchStart: string) { | ||
// Explicitly do not use 'require("dep/package.json")' because that will fail if the | ||
// package does not export that particular file. | ||
const entryPoint = require.resolve(dependencyName, { | ||
paths: [searchStart], | ||
}); | ||
|
||
// Search up from the given directory, looking for a package.json that matches | ||
// the dependency name (so we don't accidentally find stray 'package.jsons'). | ||
const depPkgJsonPath = await findPackageJsonUp(dependencyName, path.dirname(entryPoint)); | ||
|
||
if (!depPkgJsonPath) { | ||
throw new Error(`Could not find dependency '${dependencyName}' from '${searchStart}'`); | ||
} | ||
|
||
return depPkgJsonPath; | ||
} | ||
|
||
/** | ||
* Find the package.json for a given package upwards from the given directory | ||
* | ||
* (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all | ||
* 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) | ||
*/ | ||
export async function findPackageJsonUp(packageName: string, directory: string) { | ||
return findUp(directory, async (dir) => { | ||
const pjFile = path.join(dir, 'package.json'); | ||
return (await fs.pathExists(pjFile)) && (await fs.readJson(pjFile)).name === packageName; | ||
}); | ||
} | ||
|
||
/** | ||
* Find a directory up the tree from a starting directory matching a condition | ||
* | ||
* Will return `undefined` if no directory matches | ||
* | ||
* (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all | ||
* 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) | ||
*/ | ||
export function findUp(directory: string, pred: (dir: string) => Promise<boolean>): Promise<string | undefined>; | ||
export function findUp(directory: string, pred: (dir: string) => boolean): string | undefined; | ||
// eslint-disable-next-line @typescript-eslint/promise-function-async | ||
export function findUp( | ||
directory: string, | ||
pred: (dir: string) => boolean | Promise<boolean>, | ||
): Promise<string | undefined> | string | undefined { | ||
const result = pred(directory); | ||
if (result instanceof Promise) { | ||
return result.then((thisDirectory) => (thisDirectory ? directory : recurse())); | ||
} | ||
|
||
return result ? directory : recurse(); | ||
|
||
function recurse() { | ||
const parent = path.dirname(directory); | ||
if (parent === directory) { | ||
return undefined; | ||
} | ||
return findUp(parent, pred as any); | ||
} | ||
} | ||
|
||
/** | ||
* Whether the given dependency is a built-in | ||
* | ||
* Some dependencies that occur in `package.json` are also built-ins in modern Node | ||
* versions (most egregious example: 'punycode'). Detect those and filter them out. | ||
*/ | ||
export function isBuiltinModule(depName: string) { | ||
// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires | ||
const { builtinModules } = require('module'); | ||
return (builtinModules ?? []).includes(depName); | ||
} |
Oops, something went wrong.