-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(cli): disallow import of internal cli libraries (#33021)
### Reason for this change Previously it was possible to import any subpaths from the `aws-cdk` package ("the CLI"). This was never intended to be allowed, or supported. In practice, these subpaths imports allowed users to depend on internal CLI APIs that are not intended for public usage and do not receive the same backwards compatibility guarantees as other parts of the AWS CDK. **With this change we are explicitly disallowing unsanctioned subpath imports.** We are currently in the process of making most CLI features available through a new Programmatic Toolkit library. Please see the [respective RFC](aws/aws-cdk-rfcs#654) and let us know if you have a use case that is not currently covered by the proposed feature set. In order to not immediately break all customers using unsanctioned subpath imports, we have identified a subset of symbols that we will keep exporting in the short-time future. **You are still very strongly encouraged to move off any of these features asap.** We are actively considering to emit warnings and enact brown-outs to inform users of this removal. ### Description of changes Added the new legacy exports to `aws-cdk`. Also change some imports in `aws-cdk` to use the lower-level path instead of `lib/index`. In `cli-lib-alpha` we now import from the CLI package via file paths, instead of the package. This is intentional because we don't actually need or want to depended on the `aws-cdk` the package as `cli-lib-alpha` is bundling everything itself. Although we still have a dependency on `aws-cdk` at the moment because we need its build to run to produce some other artifacts. Soon these imports will change to `../../../tmp-aws-cdk/lib` and import from the temporary package that holds all library code. We already do the same in the toolkit package. ### Describe any new or updated permissions being added none ### Description of how you validated changes Existing tests ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
- Loading branch information
Showing
21 changed files
with
306 additions
and
21 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
export * from './api'; | ||
export { cli, exec } from './cli'; | ||
|
||
// Re-export the legacy exports under a name | ||
// We import and re-export them from the index.ts file to generate a single bundle of all code and dependencies | ||
export * as legacy from './legacy-exports-source'; |
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,32 @@ | ||
// This is a barrel export file, of all known symbols that are imported by users from the `aws-cdk` package. | ||
// Importing these symbols was never officially supported, but here we are. | ||
// In order to preserver backwards-compatibly for these users, we re-export and preserve them as explicit subpath exports. | ||
// See https://github.com/aws/aws-cdk/pull/33021 for more information. | ||
|
||
// Note: All type exports are in `legacy-exports.ts` | ||
export * from './legacy-logging-source'; | ||
export { deepClone, flatten, ifDefined, isArray, isEmpty, numberFromBool, partition } from './util'; | ||
export { deployStack } from './api/deploy-stack'; | ||
export { cli, exec } from './cli'; | ||
export { SdkProvider } from './api/aws-auth'; | ||
export { PluginHost } from './api/plugin'; | ||
export { contentHash } from './util/content-hash'; | ||
export { Command, Configuration, PROJECT_CONTEXT, Settings } from './settings'; | ||
export { Bootstrapper } from './api/bootstrap'; | ||
export { CloudExecutable } from './api/cxapp/cloud-executable'; | ||
export { execProgram } from './api/cxapp/exec'; | ||
export { RequireApproval } from './diff'; | ||
export { leftPad } from './api/util/string-manipulation'; | ||
export { formatAsBanner } from './util/console-formatters'; | ||
export { enableTracing } from './util/tracing'; | ||
export { aliases, command, describe } from './commands/docs'; | ||
export { lowerCaseFirstCharacter } from './api/hotswap/common'; | ||
export { deepMerge } from './util/objects'; | ||
export { Deployments } from './api/deployments'; | ||
export { rootDir } from './util/directories'; | ||
export { latestVersionIfHigher, versionNumber } from './version'; | ||
export { availableInitTemplates } from './init'; | ||
export { cached } from './api/aws-auth/cached'; | ||
export { CfnEvaluationException } from './api/evaluate-cloudformation-template'; | ||
export { CredentialPlugins } from './api/aws-auth/credential-plugins'; | ||
export { AwsCliCompatible } from './api/aws-auth/awscli-compatible'; |
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,91 @@ | ||
// This is the legacy symbols export file. | ||
// We export a number of known symbols that are imported by users from the `aws-cdk` package. | ||
// Importing these symbols was never officially supported, but here we are. | ||
// See https://github.com/aws/aws-cdk/pull/33021 for more information. | ||
// | ||
// In package.json, section `exports`, we declare all known subpaths as an explicit subpath export resolving to this file. | ||
// This way existing unsanctioned imports don't break immediately. | ||
// | ||
// When attempting to import a subpath other than the explicitly exported ones, the following runtime error will be thrown: | ||
// Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/private/subpath' is not defined by "exports" in aws-cdk/package.json | ||
// | ||
// TypeScript can warn users about the not-exported subpath at compile time. However it requires a reasonably modern tsconfig.json. | ||
// Specifically `moduleResolution` must be set to either "node16" or "nodenext". | ||
|
||
// We need to import the legacy exports via index.ts | ||
// This is because we will bundle all code and dependencies into index.js at build time. | ||
// It's the only place where the code exists as a working, self-contained copy. | ||
// While we could have bundled `legacy-exports.ts` separately, it would create an other copy of the pretty much identical bundle | ||
// and add an additional 16mb+ to the published package. | ||
// To avoid this, we deduplicated the bundled code and run everything through index.ts. | ||
import { legacy } from './index'; | ||
|
||
// We also need to re-export some types | ||
// These don't need to participate in the bundling, so we can just put them here | ||
export type { Obj } from './util'; | ||
export type { Account } from './api/aws-auth'; | ||
export type { ContextProviderPlugin } from './api/plugin'; | ||
export type { BootstrapEnvironmentOptions, BootstrapSource } from './api/bootstrap'; | ||
export type { StackSelector } from './api/cxapp/cloud-assembly'; | ||
export type { DeployStackResult } from './api/deploy-stack'; | ||
export type { Component } from './notices'; | ||
export type { LoggerFunction } from './legacy-logging-source'; | ||
|
||
// Re-export all symbols via index.js | ||
// We do this, because index.js is the the fail that will end up with all dependencies bundled | ||
export const { | ||
deepClone, | ||
flatten, | ||
ifDefined, | ||
isArray, | ||
isEmpty, | ||
numberFromBool, | ||
partition, | ||
deployStack, | ||
cli, | ||
exec, | ||
SdkProvider, | ||
PluginHost, | ||
contentHash, | ||
Command, | ||
Configuration, | ||
PROJECT_CONTEXT, | ||
Settings, | ||
Bootstrapper, | ||
CloudExecutable, | ||
execProgram, | ||
RequireApproval, | ||
leftPad, | ||
formatAsBanner, | ||
enableTracing, | ||
aliases, | ||
command, | ||
describe, | ||
lowerCaseFirstCharacter, | ||
deepMerge, | ||
Deployments, | ||
rootDir, | ||
latestVersionIfHigher, | ||
versionNumber, | ||
availableInitTemplates, | ||
cached, | ||
CfnEvaluationException, | ||
CredentialPlugins, | ||
AwsCliCompatible, | ||
withCorkedLogging, | ||
LogLevel, | ||
logLevel, | ||
CI, | ||
setLogLevel, | ||
setCI, | ||
increaseVerbosity, | ||
trace, | ||
debug, | ||
error, | ||
warning, | ||
success, | ||
highlight, | ||
print, | ||
data, | ||
prefix, | ||
} = legacy; |
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,122 @@ | ||
// This is an exact copy of the file `packages/aws-cdk/lib/logging.ts` from 2024-11-29 | ||
// https://github.com/aws/aws-cdk/blob/81cde0e2e1f83f80273d14724d5518cc20dc5a80/packages/aws-cdk/lib/logging.ts | ||
// After this we started refactoring the file and functionality changed significantly. | ||
// In order to preserver backwards-compatibly for users with unsanctioned usage of this file, | ||
// we keep a copy of the original version around. | ||
// See https://github.com/aws/aws-cdk/pull/33021 for more information. | ||
|
||
import { Writable } from 'stream'; | ||
import * as util from 'util'; | ||
import * as chalk from 'chalk'; | ||
|
||
type StyleFn = (str: string) => string; | ||
const { stdout, stderr } = process; | ||
|
||
type WritableFactory = () => Writable; | ||
|
||
export async function withCorkedLogging<A>(block: () => Promise<A>): Promise<A> { | ||
corkLogging(); | ||
try { | ||
return await block(); | ||
} finally { | ||
uncorkLogging(); | ||
} | ||
} | ||
|
||
let CORK_COUNTER = 0; | ||
const logBuffer: [Writable, string][] = []; | ||
|
||
function corked() { | ||
return CORK_COUNTER !== 0; | ||
} | ||
|
||
function corkLogging() { | ||
CORK_COUNTER += 1; | ||
} | ||
|
||
function uncorkLogging() { | ||
CORK_COUNTER -= 1; | ||
if (!corked()) { | ||
logBuffer.forEach(([stream, str]) => stream.write(str + '\n')); | ||
logBuffer.splice(0); | ||
} | ||
} | ||
|
||
const logger = (stream: Writable | WritableFactory, styles?: StyleFn[], timestamp?: boolean) => (fmt: string, ...args: unknown[]) => { | ||
const ts = timestamp ? `[${formatTime(new Date())}] ` : ''; | ||
|
||
let str = ts + util.format(fmt, ...args); | ||
if (styles && styles.length) { | ||
str = styles.reduce((a, style) => style(a), str); | ||
} | ||
|
||
const realStream = typeof stream === 'function' ? stream() : stream; | ||
|
||
// Logger is currently corked, so we store the message to be printed | ||
// later when we are uncorked. | ||
if (corked()) { | ||
logBuffer.push([realStream, str]); | ||
return; | ||
} | ||
|
||
realStream.write(str + '\n'); | ||
}; | ||
|
||
function formatTime(d: Date) { | ||
return `${lpad(d.getHours(), 2)}:${lpad(d.getMinutes(), 2)}:${lpad(d.getSeconds(), 2)}`; | ||
|
||
function lpad(x: any, w: number) { | ||
const s = `${x}`; | ||
return '0'.repeat(Math.max(w - s.length, 0)) + s; | ||
} | ||
} | ||
|
||
export enum LogLevel { | ||
/** Not verbose at all */ | ||
DEFAULT = 0, | ||
/** Pretty verbose */ | ||
DEBUG = 1, | ||
/** Extremely verbose */ | ||
TRACE = 2, | ||
} | ||
|
||
export let logLevel = LogLevel.DEFAULT; | ||
export let CI = false; | ||
|
||
export function setLogLevel(newLogLevel: LogLevel) { | ||
logLevel = newLogLevel; | ||
} | ||
|
||
export function setCI(newCI: boolean) { | ||
CI = newCI; | ||
} | ||
|
||
export function increaseVerbosity() { | ||
logLevel += 1; | ||
} | ||
|
||
const stream = () => CI ? stdout : stderr; | ||
const _debug = logger(stream, [chalk.gray], true); | ||
|
||
export const trace = (fmt: string, ...args: unknown[]) => logLevel >= LogLevel.TRACE && _debug(fmt, ...args); | ||
export const debug = (fmt: string, ...args: unknown[]) => logLevel >= LogLevel.DEBUG && _debug(fmt, ...args); | ||
export const error = logger(stderr, [chalk.red]); | ||
export const warning = logger(stream, [chalk.yellow]); | ||
export const success = logger(stream, [chalk.green]); | ||
export const highlight = logger(stream, [chalk.bold]); | ||
export const print = logger(stream); | ||
export const data = logger(stdout); | ||
|
||
export type LoggerFunction = (fmt: string, ...args: unknown[]) => void; | ||
|
||
/** | ||
* Create a logger output that features a constant prefix string. | ||
* | ||
* @param prefixString the prefix string to be appended before any log entry. | ||
* @param fn the logger function to be used (typically one of the other functions in this module) | ||
* | ||
* @returns a new LoggerFunction. | ||
*/ | ||
export function prefix(prefixString: string, fn: LoggerFunction): LoggerFunction { | ||
return (fmt: string, ...args: any[]) => fn(`%s ${fmt}`, prefixString, ...args); | ||
} |
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
2 changes: 1 addition & 1 deletion
2
packages/aws-cdk/test/context-providers/availability-zones.test.ts
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
2 changes: 1 addition & 1 deletion
2
packages/aws-cdk/test/context-providers/endpoint-service-availability-zones.test.ts
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
Oops, something went wrong.