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

feat: print warning on use of deprecated API #4200

Merged
merged 17 commits into from
Jan 22, 2024
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"automation/": "https://raw.githubusercontent.com/denoland/automation/0.10.0/"
},
"tasks": {
"test": "deno test --doc --unstable --allow-all --parallel --coverage --trace-ops",
"test": "NO_DEPRECATION_WARNINGS=1 deno test --doc --unstable --allow-all --parallel --coverage --trace-ops",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed for cases where we must still continue to test deprecated APIs.

"test:browser": "git grep --name-only \"This module is browser compatible.\" | grep -v deno.json | grep -v .github/workflows | grep -v _tools | xargs deno check --config browser-compat.tsconfig.json",
"fmt:licence-headers": "deno run --allow-read --allow-write ./_tools/check_licence.ts",
"lint:deprecations": "deno run --allow-read --allow-net --allow-env=HOME ./_tools/check_deprecation.ts",
Expand Down
9 changes: 9 additions & 0 deletions internal/mod.ts
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does having an internal folder interfere with workspaces functionality, @lucacasonato?

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

/**
* Internal utilities for the public API of the Deno Standard Library.
*
* Note: for internal use only.
*
* @module
*/
94 changes: 94 additions & 0 deletions internal/warn_on_deprecated_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.

// deno-lint-ignore no-explicit-any
const { Deno } = globalThis as any;

const ALREADY_WARNED_DEPRECATED = new Set<string>();

interface WarnDeprecatedApiConfig {
/** The name of the deprecated API. */
apiName: string;
/** The stack trace of the deprecated API. */
stack: string;
/** The version in which the API will be removed. */
removalVersion: string;
/** An optional message to print. */
suggestion?: string;
}

/**
* Prints a warning message to the console for the given deprecated API.
*
* These warnings can be disabled by setting `NO_DEPRECATION_WARNINGS=1`
* in the current process.
*/
export function warnOnDeprecatedApi(config: WarnDeprecatedApiConfig) {
const variable = "NO_DEPRECATION_WARNINGS";
if (
Deno?.permissions.querySync({ name: "env", variable }).state ===
iuioiua marked this conversation as resolved.
Show resolved Hide resolved
"granted" && Deno?.env.get(variable) === "1"
) return;

const key = config.apiName + config.stack;
if (ALREADY_WARNED_DEPRECATED.has(key)) return;

Check warning on line 34 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L33-L34

Added lines #L33 - L34 were not covered by tests

// If we haven't warned yet, let's do some processing of the stack trace
// to make it more useful.
const stackLines = config.stack.split("\n");
stackLines.shift();

Check warning on line 39 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L36-L39

Added lines #L36 - L39 were not covered by tests

let isFromRemoteDependency = false;
const firstStackLine = stackLines[0];

Check warning on line 42 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L41-L42

Added lines #L41 - L42 were not covered by tests
if (firstStackLine && !firstStackLine.includes("file:")) {
isFromRemoteDependency = true;
}

Check warning on line 45 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L44-L45

Added lines #L44 - L45 were not covered by tests

ALREADY_WARNED_DEPRECATED.add(key);
console.log(
"%cWarning",
"color: yellow; font-weight: bold;",

Check warning on line 50 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L47-L50

Added lines #L47 - L50 were not covered by tests
);
console.log(
`%c\u251c Use of deprecated "${config.apiName}" API.`,
"color: yellow;",

Check warning on line 54 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L52-L54

Added lines #L52 - L54 were not covered by tests
);
console.log("%c\u2502", "color: yellow;");
console.log(
`%c\u251c This API will be removed in version ${config.removalVersion} of the Deno Standard Library.`,
"color: yellow;",

Check warning on line 59 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L56-L59

Added lines #L56 - L59 were not covered by tests
);
console.log("%c\u2502", "color: yellow;");
console.log(
`%c\u251c Suggestion: ${config.suggestion}`,
"color: yellow;",

Check warning on line 64 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L61-L64

Added lines #L61 - L64 were not covered by tests
);
if (isFromRemoteDependency) {
console.log("%c\u2502", "color: yellow;");
console.log(
`%c\u251c Suggestion: It appears this API is used by a remote dependency.`,
"color: yellow;",

Check warning on line 70 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L66-L70

Added lines #L66 - L70 were not covered by tests
);
console.log(
"%c\u2502 Try upgrading to the latest version of that dependency.",
"color: yellow;",

Check warning on line 74 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L72-L74

Added lines #L72 - L74 were not covered by tests
);
}

Check warning on line 76 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L76

Added line #L76 was not covered by tests

console.log("%c\u2502", "color: yellow;");
console.log("%c\u2502", "color: yellow;");
console.log(
"%c\u251c Set `NO_DEPRECATION_WARNINGS=1` to disable these deprecation warnings.",
"color: yellow;",

Check warning on line 82 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L78-L82

Added lines #L78 - L82 were not covered by tests
);
console.log("%c\u2514 Stack trace:", "color: yellow;");
for (let i = 0; i < stackLines.length; i++) {
console.log(
`%c ${i == stackLines.length - 1 ? "\u2514" : "\u251c"}\u2500 ${
stackLines[i].trim()
}`,
"color: yellow;",

Check warning on line 90 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L84-L90

Added lines #L84 - L90 were not covered by tests
);
}
console.log();

Check warning on line 93 in internal/warn_on_deprecated_api.ts

View check run for this annotation

Codecov / codecov/patch

internal/warn_on_deprecated_api.ts#L92-L93

Added lines #L92 - L93 were not covered by tests
}
13 changes: 13 additions & 0 deletions streams/read_all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
readAllSync as _readAllSync,
} from "../io/read_all.ts";
import type { Reader, ReaderSync } from "../io/types.ts";
import { warnOnDeprecatedApi } from "../internal/warn_on_deprecated_api.ts";

/**
* Read {@linkcode Reader} `r` until EOF (`null`) and resolve to the content as
Expand Down Expand Up @@ -33,6 +34,12 @@ import type { Reader, ReaderSync } from "../io/types.ts";
* @deprecated (will be removed in 0.214.0) Import from {@link https://deno.land/std/io/read_all.ts} instead.
*/
export async function readAll(r: Reader): Promise<Uint8Array> {
warnOnDeprecatedApi({
apiName: "readAll()",
stack: new Error().stack!,
removalVersion: "0.214.0",
suggestion: "Import from `https://deno.land/std/io/read_all.ts` instead.",
});
return await _readAll(r);
}

Expand Down Expand Up @@ -62,5 +69,11 @@ export async function readAll(r: Reader): Promise<Uint8Array> {
* @deprecated (will be removed in 0.214.0) Import from {@link https://deno.land/std/io/read_all.ts} instead.
*/
export function readAllSync(r: ReaderSync): Uint8Array {
warnOnDeprecatedApi({
apiName: "readAllSync()",
stack: new Error().stack!,
removalVersion: "0.214.0",
suggestion: "Import from `https://deno.land/std/io/read_all.ts` instead.",
});
return _readAllSync(r);
}