refactor(using): use using keyword for Explicit Resource Management (#4143)

* refactor(using): add using keyword for Explicit Resource Management

* refactor(using): fix fmt

* refactor(using): add more fixes

* refactor(using): fix fmt

* refactor: add more `using` cases

---------

Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
This commit is contained in:
Anwesh 2024-01-15 03:05:50 +05:30 committed by GitHub
parent aa3f026e93
commit 3fcb0a8b24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 46 additions and 108 deletions

View File

@ -110,17 +110,15 @@ Deno.test("Tar() checks directory entry type", async function () {
});
const outputFile = resolve(testdataDir, "directory_type_test.tar");
const file = await Deno.open(outputFile, { create: true, write: true });
using file = await Deno.open(outputFile, { create: true, write: true });
await copy(tar.getReader(), file);
file.close();
const reader = await Deno.open(outputFile, { read: true });
using reader = await Deno.open(outputFile, { read: true });
const untar = new Untar(reader);
await Array.fromAsync(
untar,
(entry) => assertEquals(entry.type, "directory"),
);
reader.close();
await Deno.remove(outputFile);
});

View File

@ -187,7 +187,7 @@ export class TarEntry implements Reader {
* import { ensureDir } from "https://deno.land/std@$STD_VERSION/fs/ensure_dir.ts";
* import { copy } from "https://deno.land/std@$STD_VERSION/streams/copy.ts";
*
* const reader = await Deno.open("./out.tar", { read: true });
* using reader = await Deno.open("./out.tar", { read: true });
* const untar = new Untar(reader);
*
* for await (const entry of untar) {
@ -199,11 +199,10 @@ export class TarEntry implements Reader {
* }
*
* await ensureFile(entry.fileName);
* const file = await Deno.open(entry.fileName, { write: true });
* using file = await Deno.open(entry.fileName, { write: true });
* // <entry> is a reader.
* await copy(entry, file);
* }
* reader.close();
* ```
*/
export class Untar {

View File

@ -120,11 +120,10 @@ Deno.test(
const outputFile = resolve(testdataDir, "test.tar");
const tar = await createTar(entries);
const file = await Deno.open(outputFile, { create: true, write: true });
using file = await Deno.open(outputFile, { create: true, write: true });
await copy(tar.getReader(), file);
file.close();
const reader = await Deno.open(outputFile, { read: true });
using reader = await Deno.open(outputFile, { read: true });
// read data from a tar archive
const untar = new Untar(reader);
@ -134,7 +133,6 @@ Deno.test(
assertEquals(expected.name, entry.fileName);
}
reader.close();
await Deno.remove(outputFile);
assertEquals(entries.length, 0);
},
@ -155,11 +153,10 @@ Deno.test("Untar() reads from FileReader", async () => {
const outputFile = resolve(testdataDir, "test.tar");
const tar = await createTar(entries);
const file = await Deno.open(outputFile, { create: true, write: true });
using file = await Deno.open(outputFile, { create: true, write: true });
await copy(tar.getReader(), file);
file.close();
const reader = await Deno.open(outputFile, { read: true });
using reader = await Deno.open(outputFile, { read: true });
// read data from a tar archive
const untar = new Untar(reader);
@ -176,7 +173,6 @@ Deno.test("Untar() reads from FileReader", async () => {
assertEquals(expected.name, entry.fileName);
}
reader.close();
await Deno.remove(outputFile);
assertEquals(entries.length, 0);
});
@ -229,7 +225,7 @@ Deno.test(
Deno.test("Untar() works with Linux generated tar", async () => {
const filePath = resolve(testdataDir, "deno.tar");
const file = await Deno.open(filePath, { read: true });
using file = await Deno.open(filePath, { read: true });
type ExpectedEntry = TarMeta & { content?: Uint8Array };
@ -319,8 +315,6 @@ Deno.test("Untar() works with Linux generated tar", async () => {
assertEquals(content, await readAll(entry));
}
}
file.close();
});
Deno.test({
@ -369,7 +363,7 @@ Deno.test({
Deno.test("Untar() handles archive with link", async function () {
const filePath = resolve(testdataDir, "with_link.tar");
const file = await Deno.open(filePath, { read: true });
using file = await Deno.open(filePath, { read: true });
type ExpectedEntry = TarMetaWithLinkName & { content?: Uint8Array };
@ -414,6 +408,4 @@ Deno.test("Untar() handles archive with link", async function () {
assertEquals(content, await readAll(entry));
}
}
file.close();
});

View File

@ -24,7 +24,7 @@ Deno.test("existsSync() returns false for a non-existent path", function () {
Deno.test("exists() returns true for an existing file", async function () {
const tempDirPath = await Deno.makeTempDir();
const tempFilePath = path.join(tempDirPath, "0.ts");
const tempFile = await Deno.create(tempFilePath);
using _tempFile = await Deno.create(tempFilePath);
try {
assertEquals(await exists(tempFilePath), true);
assertEquals(await exists(tempFilePath, {}), true);
@ -54,7 +54,6 @@ Deno.test("exists() returns true for an existing file", async function () {
if (Deno.build.os !== "windows") {
await Deno.chmod(tempFilePath, 0o644);
}
tempFile.close();
await Deno.remove(tempDirPath, { recursive: true });
}
});
@ -63,7 +62,7 @@ Deno.test("exists() returns true for an existing file symlink", async function (
const tempDirPath = await Deno.makeTempDir();
const tempFilePath = path.join(tempDirPath, "0.ts");
const tempLinkFilePath = path.join(tempDirPath, "0-link.ts");
const tempFile = await Deno.create(tempFilePath);
using _tempFile = await Deno.create(tempFilePath);
try {
await Deno.symlink(tempFilePath, tempLinkFilePath);
assertEquals(await exists(tempLinkFilePath), true);
@ -95,7 +94,6 @@ Deno.test("exists() returns true for an existing file symlink", async function (
if (Deno.build.os !== "windows") {
await Deno.chmod(tempFilePath, 0o644);
}
tempFile.close();
await Deno.remove(tempDirPath, { recursive: true });
}
});
@ -103,7 +101,7 @@ Deno.test("exists() returns true for an existing file symlink", async function (
Deno.test("existsSync() returns true for an existing file", function () {
const tempDirPath = Deno.makeTempDirSync();
const tempFilePath = path.join(tempDirPath, "0.ts");
const tempFile = Deno.createSync(tempFilePath);
using _tempFile = Deno.createSync(tempFilePath);
try {
assertEquals(existsSync(tempFilePath), true);
assertEquals(existsSync(tempFilePath, {}), true);
@ -133,7 +131,6 @@ Deno.test("existsSync() returns true for an existing file", function () {
if (Deno.build.os !== "windows") {
Deno.chmodSync(tempFilePath, 0o644);
}
tempFile.close();
Deno.removeSync(tempDirPath, { recursive: true });
}
});
@ -142,7 +139,7 @@ Deno.test("existsSync() returns true for an existing file symlink", function ()
const tempDirPath = Deno.makeTempDirSync();
const tempFilePath = path.join(tempDirPath, "0.ts");
const tempLinkFilePath = path.join(tempDirPath, "0-link.ts");
const tempFile = Deno.createSync(tempFilePath);
using _tempFile = Deno.createSync(tempFilePath);
try {
Deno.symlinkSync(tempFilePath, tempLinkFilePath);
assertEquals(existsSync(tempLinkFilePath), true);
@ -174,7 +171,6 @@ Deno.test("existsSync() returns true for an existing file symlink", function ()
if (Deno.build.os !== "windows") {
Deno.chmodSync(tempFilePath, 0o644);
}
tempFile.close();
Deno.removeSync(tempDirPath, { recursive: true });
}
});

View File

@ -169,11 +169,10 @@ Deno.test({
async fn() {
const path = resolve(testdataDir, "socket", "a.sock");
try {
const listener = Deno.listen({ path, transport: "unix" });
using _listener = Deno.listen({ path, transport: "unix" });
await assertWalkPaths("socket", [".", "a.sock", ".gitignore"], {
followSymlinks: true,
});
listener.close();
} finally {
await Deno.remove(path);
}
@ -187,11 +186,10 @@ Deno.test({
async fn() {
const path = resolve(testdataDir, "socket", "a.sock");
try {
const listener = Deno.listen({ path, transport: "unix" });
using _listener = Deno.listen({ path, transport: "unix" });
assertWalkSyncPaths("socket", [".", "a.sock", ".gitignore"], {
followSymlinks: true,
});
listener.close();
} finally {
await Deno.remove(path);
}

View File

@ -299,8 +299,7 @@ Deno.test("serveDir() traverses encoded URI path", async () => {
Deno.test("serveDir() serves unusual filename", async () => {
const filePath = join(testdataDir, "%");
const file = await Deno.create(filePath);
file.close();
using _file = await Deno.create(filePath);
const req1 = new Request("http://localhost/%25");
const res1 = await serveDir(req1, serveDirOptions);

View File

@ -218,21 +218,13 @@ Deno.test(
hostname: "localhost",
port: getPort(),
};
const listener = Deno.listen(listenOptions);
using listener = Deno.listen(listenOptions);
await assertRejects(
() => server.serve(listener),
Deno.errors.Http,
"Server closed",
);
try {
listener.close();
} catch (error) {
if (!(error instanceof Deno.errors.BadResource)) {
throw error;
}
}
},
);
@ -548,7 +540,7 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
try {
// Invalid certificate, connection should throw on first read or write
// but should not crash the server.
const badConn = await Deno.connectTls({
using badConn = await Deno.connectTls({
hostname,
port,
// missing certFile
@ -561,10 +553,8 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
"Read with missing certFile didn't throw an InvalidData error when it should have.",
);
badConn.close();
// Valid request after invalid
const conn = await Deno.connectTls({
using conn = await Deno.connectTls({
hostname,
port,
certFile: join(testdataDir, "tls/RootCA.pem"),
@ -577,8 +567,6 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
const response = new TextDecoder().decode(await readAll(conn));
conn.close();
assert(response.includes(`HTTP/1.0 ${status}`), "Status code not correct");
assert(response.includes(body), "Response body not correct");
} finally {
@ -612,7 +600,7 @@ Deno.test({
try {
// Invalid certificate, connection should throw on first read or write
// but should not crash the server.
const badConn = await Deno.connectTls({
using badConn = await Deno.connectTls({
hostname,
port,
// missing certFile
@ -625,10 +613,8 @@ Deno.test({
"Read with missing certFile didn't throw an InvalidData error when it should have.",
);
badConn.close();
// Valid request after invalid
const conn = await Deno.connectTls({
using conn = await Deno.connectTls({
hostname,
port,
certFile: join(testdataDir, "tls/RootCA.pem"),
@ -641,8 +627,6 @@ Deno.test({
const response = new TextDecoder().decode(await readAll(conn));
conn.close();
assert(
response.includes(`HTTP/1.0 ${status}`),
"Status code not correct",
@ -797,7 +781,7 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
try {
// Invalid certificate, connection should throw on first read or write
// but should not crash the server.
const badConn = await Deno.connectTls({
using badConn = await Deno.connectTls({
hostname,
port,
// missing certFile
@ -810,10 +794,8 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
"Read with missing certFile didn't throw an InvalidData error when it should have.",
);
badConn.close();
// Valid request after invalid
const conn = await Deno.connectTls({
using conn = await Deno.connectTls({
hostname,
port,
certFile: join(testdataDir, "tls/RootCA.pem"),
@ -826,8 +808,6 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
const response = new TextDecoder().decode(await readAll(conn));
conn.close();
assert(response.includes(`HTTP/1.0 ${status}`), "Status code not correct");
assert(response.includes(body), "Response body not correct");
} finally {
@ -839,10 +819,9 @@ Deno.test(`Server.listenAndServeTls should handle requests`, async () => {
Deno.test(
"Server should not reject when the listener is closed (though the server will continually try and fail to accept connections on the listener until it is closed)",
async () => {
const listener = Deno.listen({ port: getPort() });
using listener = Deno.listen({ port: getPort() });
const handler = () => new Response();
const server = new Server({ handler });
listener.close();
let servePromise;
@ -1099,12 +1078,11 @@ Deno.test(
const server = new Server({ handler });
const servePromise = server.serve(listener);
const conn = await Deno.connect(listenOptions);
using conn = await Deno.connect(listenOptions);
await writeAll(conn, new TextEncoder().encode(`GET / HTTP/1.0\r\n\r\n`));
await onRequest.promise;
conn.close();
await postRespondWith.promise;
server.close();
@ -1133,12 +1111,11 @@ Deno.test("Server should not reject when the handler throws", async () => {
const server = new Server({ handler });
const servePromise = server.serve(listener);
const conn = await Deno.connect(listenOptions);
using conn = await Deno.connect(listenOptions);
await writeAll(conn, new TextEncoder().encode(`GET / HTTP/1.0\r\n\r\n`));
await postRespondWith.promise;
conn.close();
server.close();
await servePromise;
});
@ -1476,7 +1453,7 @@ Deno.test("Server.listenAndServeTls should support custom onError", async () =>
});
try {
const conn = await Deno.connectTls({
using conn = await Deno.connectTls({
hostname,
port,
certFile: join(testdataDir, "tls/RootCA.pem"),
@ -1491,8 +1468,6 @@ Deno.test("Server.listenAndServeTls should support custom onError", async () =>
const response = new TextDecoder().decode(await readAll(conn));
conn.close();
assert(
response.includes(`HTTP/1.0 ${status}`),
"Status code not correct",

View File

@ -24,13 +24,12 @@ Deno.test("testCopyN2", async function () {
Deno.test("copyNWriteAllData", async function () {
const tmpDir = await Deno.makeTempDir();
const filepath = `${tmpDir}/data`;
const file = await Deno.open(filepath, { create: true, write: true });
using file = await Deno.open(filepath, { create: true, write: true });
const size = 16 * 1024 + 1;
const data = "a".repeat(32 * 1024);
const r = new StringReader(data);
const n = await copyN(r, file, size); // Over max file possible buffer
file.close();
await Deno.remove(filepath);
assertEquals(n, size);

View File

@ -17,9 +17,8 @@ import type { Reader, ReaderSync } from "./types.ts";
* const stdinContent = await readAll(Deno.stdin);
*
* // Example from file
* const file = await Deno.open("my_file.txt", {read: true});
* using file = await Deno.open("my_file.txt", {read: true});
* const myFileContent = await readAll(file);
* file.close();
* ```
*/
export async function readAll(reader: Reader): Promise<Uint8Array> {
@ -50,9 +49,8 @@ export async function readAll(reader: Reader): Promise<Uint8Array> {
* const stdinContent = readAllSync(Deno.stdin);
*
* // Example from file
* const file = Deno.openSync("my_file.txt", {read: true});
* using file = Deno.openSync("my_file.txt", {read: true});
* const myFileContent = readAllSync(file);
* file.close();
* ```
*/
export function readAllSync(reader: ReaderSync): Uint8Array {

View File

@ -56,14 +56,12 @@ Deno.test("readStringDelimAndLines", async function () {
Deno.test("readLinesWithEncodingISO-8859-15", async function () {
const lines_ = [];
const file_ = await Deno.open("./io/testdata/iso-8859-15.txt");
using file_ = await Deno.open("./io/testdata/iso-8859-15.txt");
for await (const l of readLines(file_, { encoding: "iso-8859-15" })) {
lines_.push(l);
}
file_.close();
assertEquals(lines_.length, 12);
assertEquals(lines_, [
"\u0020!\"#$%&'()*+,-./",

View File

@ -16,9 +16,8 @@ import type { Writer, WriterSync } from "./types.ts";
*
* // Example writing to file
* contentBytes = new TextEncoder().encode("Hello World");
* const file = await Deno.open('test.file', {write: true});
* using file = await Deno.open('test.file', {write: true});
* await writeAll(file, contentBytes);
* file.close();
* ```
*/
export async function writeAll(writer: Writer, data: Uint8Array) {
@ -42,9 +41,8 @@ export async function writeAll(writer: Writer, data: Uint8Array) {
*
* // Example writing to file
* contentBytes = new TextEncoder().encode("Hello World");
* const file = Deno.openSync('test.file', {write: true});
* using file = Deno.openSync('test.file', {write: true});
* writeAllSync(file, contentBytes);
* file.close();
* ```
*/
export function writeAllSync(writer: WriterSync, data: Uint8Array) {

View File

@ -24,8 +24,7 @@ export function getAvailablePort(options?: GetAvailablePortOptions): number {
if (options?.preferredPort) {
try {
// Check if the preferred port is available
const listener = Deno.listen({ port: options.preferredPort });
listener.close();
using listener = Deno.listen({ port: options.preferredPort });
return (listener.addr as Deno.NetAddr).port;
} catch (e) {
// If the preferred port is not available, fall through and find an available port
@ -35,7 +34,6 @@ export function getAvailablePort(options?: GetAvailablePortOptions): number {
}
}
const listener = Deno.listen({ port: 0 });
listener.close();
using listener = Deno.listen({ port: 0 });
return (listener.addr as Deno.NetAddr).port;
}

View File

@ -13,11 +13,10 @@ export type { Reader, ReaderSync };
* ```ts
* import { iterateReader } from "https://deno.land/std@$STD_VERSION/streams/iterate_reader.ts";
*
* let f = await Deno.open("/etc/passwd");
* using f = await Deno.open("/etc/passwd");
* for await (const chunk of iterateReader(f)) {
* console.log(chunk);
* }
* f.close();
* ```
*
* Second argument can be used to tune size of a buffer.
@ -27,14 +26,13 @@ export type { Reader, ReaderSync };
* ```ts
* import { iterateReader } from "https://deno.land/std@$STD_VERSION/streams/iterate_reader.ts";
*
* let f = await Deno.open("/etc/passwd");
* using f = await Deno.open("/etc/passwd");
* const it = iterateReader(f, {
* bufSize: 1024 * 1024
* });
* for await (const chunk of it) {
* console.log(chunk);
* }
* f.close();
* ```
*
* @deprecated (will be removed after 1.0.0) Use {@linkcode ReadableStream} instead.
@ -63,11 +61,10 @@ export async function* iterateReader(
* ```ts
* import { iterateReaderSync } from "https://deno.land/std@$STD_VERSION/streams/iterate_reader.ts";
*
* let f = Deno.openSync("/etc/passwd");
* using f = Deno.openSync("/etc/passwd");
* for (const chunk of iterateReaderSync(f)) {
* console.log(chunk);
* }
* f.close();
* ```
*
* Second argument can be used to tune size of a buffer.
@ -76,14 +73,13 @@ export async function* iterateReader(
* ```ts
* import { iterateReaderSync } from "https://deno.land/std@$STD_VERSION/streams/iterate_reader.ts";
* let f = await Deno.open("/etc/passwd");
* using f = await Deno.open("/etc/passwd");
* const iter = iterateReaderSync(f, {
* bufSize: 1024 * 1024
* });
* for (const chunk of iter) {
* console.log(chunk);
* }
* f.close();
* ```
*
* Iterator uses an internal buffer of fixed size for efficiency; it returns

View File

@ -18,9 +18,8 @@ import type { Reader, ReaderSync } from "../io/types.ts";
* const stdinContent = await readAll(Deno.stdin);
*
* // Example from file
* const file = await Deno.open("my_file.txt", {read: true});
* using file = await Deno.open("my_file.txt", {read: true});
* const myFileContent = await readAll(file);
* file.close();
*
* // Example from buffer
* const myData = new Uint8Array(100);
@ -48,9 +47,8 @@ export async function readAll(r: Reader): Promise<Uint8Array> {
* const stdinContent = readAllSync(Deno.stdin);
*
* // Example from file
* const file = Deno.openSync("my_file.txt", {read: true});
* using file = Deno.openSync("my_file.txt", {read: true});
* const myFileContent = readAllSync(file);
* file.close();
*
* // Example from buffer
* const myData = new Uint8Array(100);

View File

@ -14,11 +14,10 @@ import type { Reader } from "../io/types.ts";
* import { readerFromStreamReader } from "https://deno.land/std@$STD_VERSION/streams/reader_from_stream_reader.ts";
*
* const res = await fetch("https://deno.land");
* const file = await Deno.open("./deno.land.html", { create: true, write: true });
* using file = await Deno.open("./deno.land.html", { create: true, write: true });
*
* const reader = readerFromStreamReader(res.body!.getReader());
* await copy(reader, file);
* file.close();
* ```
*
* @deprecated (will be removed after 1.0.0) Use {@linkcode ReadableStreamDefaultReader} directly.

View File

@ -19,9 +19,8 @@ export type { Writer, WriterSync };
*
* // Example writing to file
* contentBytes = new TextEncoder().encode("Hello World");
* const file = await Deno.open('test.file', {write: true});
* using file = await Deno.open('test.file', {write: true});
* await writeAll(file, contentBytes);
* file.close();
*
* // Example writing to buffer
* contentBytes = new TextEncoder().encode("Hello World");
@ -50,9 +49,8 @@ export async function writeAll(w: Writer, arr: Uint8Array) {
*
* // Example writing to file
* contentBytes = new TextEncoder().encode("Hello World");
* const file = Deno.openSync('test.file', {write: true});
* using file = Deno.openSync('test.file', {write: true});
* writeAllSync(file, contentBytes);
* file.close();
*
* // Example writing to buffer
* contentBytes = new TextEncoder().encode("Hello World");

View File

@ -11,7 +11,7 @@ import type { Writer } from "../io/types.ts";
* import { copy } from "https://deno.land/std@$STD_VERSION/streams/copy.ts";
* import { writerFromStreamWriter } from "https://deno.land/std@$STD_VERSION/streams/writer_from_stream_writer.ts";
*
* const file = await Deno.open("./deno.land.html", { read: true });
* using file = await Deno.open("./deno.land.html", { read: true });
*
* const writableStream = new WritableStream({
* write(chunk): void {
@ -20,7 +20,6 @@ import type { Writer } from "../io/types.ts";
* });
* const writer = writerFromStreamWriter(writableStream.getWriter());
* await copy(file, writer);
* file.close();
* ```
*
* @deprecated (will be removed after 1.0.0) Use {@linkcode WritableStreamDefaultWriter} directly.