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(fs): undo deprecation of exists and add permission and type check to it #2785

Merged
merged 31 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ed2627a
feat(fs): `readable`, `readableDir` and `readableFile`
Oct 18, 2022
4c25f35
docs(fs): correct `readableSync`, `readableDirSync` and `readableFile…
Oct 18, 2022
591dc13
refactor(fs): `readable*` to `isReadable*`
Oct 18, 2022
99dc87a
fix(fs): `isReadable*` handles permissions
Oct 19, 2022
47e2c30
chore(fs): Remove irrelevant TODOs
Oct 19, 2022
a5612af
Merge branch 'denoland:main' into exists-substitute
Nov 15, 2022
bf1ff4f
refactor(fs): combine isReadable* to isReadable
Nov 15, 2022
c5c3b54
refactor(fs): `isReadable` to `exists` with optional permission check
Nov 16, 2022
029f86c
chore(fs): update formatting on exists
Nov 16, 2022
19a20b5
docs(fs): u`exists` options usage
Nov 16, 2022
61b3cbe
feat(fs): `exists` permission test scenes
Nov 17, 2022
7032f68
chore(fs): strong OS comparison at `exists` tests
Nov 17, 2022
3fa4fea
Merge commit 'a03fab1991db4b83bd69a70d15a32a80302aabe2' into exists-s…
Jan 25, 2023
4ca6776
Merge commit 'cf14c9b21234f8d99ac1ae819d912e98de47be9c' into exists-s…
Mar 20, 2023
f75ce82
chore(fs): lint exists
Mar 20, 2023
addf0a9
docs(fs): adjust exists comment for actual implementation
Mar 20, 2023
3989203
docs(fs): undo adding removed README.md
Mar 20, 2023
4643479
docs(fs): add default values for ExistsOptions
Mar 20, 2023
ccee9d4
docs(fs): improved grammar and details on exists
Mar 20, 2023
1dca1ba
chore(fs): remove former ignore-deprecation rules for exists
Mar 21, 2023
9743c8b
chore(fs): add missing type definition in a test
Mar 21, 2023
87f3a6a
fix(fs): chmod calls on Windows exists tests
Mar 22, 2023
f4ae4e5
chore(fs): remove unnecessary type annotations
Mar 24, 2023
5c29166
refactor(fs): fictional to reversed exists on test scenes
Mar 24, 2023
d026283
chore(fs): remove unnecessary catch blocks
Mar 24, 2023
d53ccff
Merge commit '829f5eef214977046ca8d2c0576d37e36bd6bed5' into exists-s…
Mar 24, 2023
e401c95
Merge commit 'b2d7191d04481b74b44fe513cf66115e94237e92' into exists-s…
Mar 24, 2023
d0afa08
fix(fs): typo in output check of 4th exists test scene
Mar 24, 2023
e1ce885
Merge commit '5c6ee0e8d4e204bf45a0b848b492cf0f3189d51c' into exists-s…
Mar 24, 2023
f98df6f
Merge commit 'a99b908b5c3d6ad5ee36d0776989e2b445bf3ba9' into exists-s…
Mar 27, 2023
626da89
Merge branch 'main' into exists-substitute
kt3k Mar 30, 2023
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
3 changes: 3 additions & 0 deletions fs/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export * from "./ensure_dir.ts";
export * from "./ensure_file.ts";
export * from "./ensure_link.ts";
export * from "./ensure_symlink.ts";
export * from "./readable.ts";
export * from "./readable_dir.ts";
export * from "./readable_file.ts";
export * from "./exists.ts";
export * from "./expand_glob.ts";
export * from "./move.ts";
Expand Down
81 changes: 81 additions & 0 deletions fs/readable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.

/**
* Test whether or not the given path is readable by checking with the file system. To check simultaneously if the path is either a file or a directory please use `readableFile` or `readableDir` instead.
*
* Note: do not use this function if performing a check before another operation on that file. Doing so creates a race condition. Instead, perform the actual file operation directly.
*
* Bad:
* ```ts
* import { readable } from "https://deno.land/std@$STD_VERSION/fs/mod.ts";
*
* if (await readable("./foo")) {
* await Deno.remove("./foo");
* }
* ```
*
* Good:
* ```ts
* // Notice no use of readable
* try {
* await Deno.remove("./foo", { recursive: true });
* } catch (error) {
* if (!(error instanceof Deno.errors.NotFound)) {
* throw error;
* }
* // Do nothing...
* }
* ```
* @see https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
*/
export async function readable(path: string | URL): Promise<boolean> {
try {
await Deno.stat(path);
return true;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return false;
}
throw error;
}
}

/**
* Test whether or not the given path is readable by checking with the file system. To check simultaneously if the path is either a file or a directory please use `readableFile` or `readableDir` instead.
*
* Note: do not use this function if performing a check before another operation on that file. Doing so creates a race condition. Instead, perform the actual file operation directly.
*
* Bad:
* ```ts
* import { readable } from "https://deno.land/std@$STD_VERSION/fs/mod.ts";
*
* if (await readable("./foo")) {
martin-braun marked this conversation as resolved.
Show resolved Hide resolved
* await Deno.remove("./foo");
* }
* ```
*
* Good:
* ```ts
* // Notice no use of readable
* try {
* await Deno.remove("./foo", { recursive: true });
* } catch (error) {
* if (!(error instanceof Deno.errors.NotFound)) {
* throw error;
* }
* // Do nothing...
* }
* ```
* @see https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
*/
export function readableSync(path: string | URL): boolean {
try {
Deno.statSync(path);
return true;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return false;
}
throw error;
}
}
79 changes: 79 additions & 0 deletions fs/readable_dir.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.

/**
* Test whether or not the given path is readable directory by checking with the file system.
*
* Note: do not use this function if performing a check before another operation on that file. Doing so creates a race condition. Instead, perform the actual file operation directly.
*
* Bad:
* ```ts
* import { readableDir } from "https://deno.land/std@$STD_VERSION/fs/mod.ts";
*
* if (await readableDir("./foo")) {
* await Deno.remove("./foo");
* }
* ```
*
* Good:
* ```ts
* // Notice no use of readableDir
* try {
* await Deno.remove("./foo", { recursive: true });
* } catch (error) {
* if (!(error instanceof Deno.errors.NotFound)) {
* throw error;
* }
* // Do nothing...
* }
* ```
* @see https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
*/
export async function readableDir(dirPath: string | URL): Promise<boolean> {
try {
return (await Deno.stat(dirPath)).isDirectory;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return false;
}
throw error;
}
}

/**
* Test whether or not the given path is readable directory by checking with the file system.
*
* Note: do not use this function if performing a check before another operation on that file. Doing so creates a race condition. Instead, perform the actual file operation directly.
*
* Bad:
* ```ts
* import { readableDir } from "https://deno.land/std@$STD_VERSION/fs/mod.ts";
*
* if (await readableDir("./foo")) {
martin-braun marked this conversation as resolved.
Show resolved Hide resolved
* await Deno.remove("./foo");
* }
* ```
*
* Good:
* ```ts
* // Notice no use of readableDir
* try {
* await Deno.remove("./foo", { recursive: true });
* } catch (error) {
* if (!(error instanceof Deno.errors.NotFound)) {
* throw error;
* }
* // Do nothing...
* }
* ```
* @see https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
*/
export function readableDirSync(dirPath: string | URL): boolean {
try {
return Deno.statSync(dirPath).isDirectory;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return false;
}
throw error;
}
}
61 changes: 61 additions & 0 deletions fs/readable_dir_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
import { assertEquals } from "../testing/asserts.ts";
import * as path from "../path/mod.ts";
import { readableDir, readableDirSync } from "./readable_dir.ts";

const moduleDir = path.dirname(path.fromFileUrl(import.meta.url));
const testdataDir = path.resolve(moduleDir, "testdata");

Deno.test("[fs] readableFile", async function () {
assertEquals(
await readableDir(path.join(testdataDir, "not_exist_file.ts")),
false,
);
assertEquals(await readableDir(path.join(testdataDir, "0.ts")), false);
});

Deno.test("[fs] readableFileSync", function () {
assertEquals(readableDirSync(path.join(testdataDir, "not_exist_file.ts")), false);
assertEquals(readableDirSync(path.join(testdataDir, "0.ts")), false);
});

Deno.test("[fs] readableDir", async function () {
assertEquals(
await readableDir(path.join(testdataDir, "not_exist_directory")),
false,
);
assertEquals(await readableDir(testdataDir), true);
});

Deno.test("[fs] readableDirSync", function () {
assertEquals(
readableDirSync(path.join(testdataDir, "not_exist_directory")),
false,
);
assertEquals(readableDirSync(testdataDir), true);
});

Deno.test("[fs] readableFileLink", async function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(await readableDir(path.join(testdataDir, "0-link")), false);
});

Deno.test("[fs] readableFileLinkSync", function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(readableDirSync(path.join(testdataDir, "0-link")), false);
});

Deno.test("[fs] readableDirLink", async function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(await readableDir(path.join(testdataDir, "testdata-link")), true);
});

Deno.test("[fs] readableDirLinkSync", function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(readableDirSync(path.join(testdataDir, "testdata-link")), true);
});

79 changes: 79 additions & 0 deletions fs/readable_file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.

/**
* Test whether or not the given path is a readable file by checking with the file system.
*
* Note: do not use this function if performing a check before another operation on that file. Doing so creates a race condition. Instead, perform the actual file operation directly.
*
* Bad:
* ```ts
* import { readableFile } from "https://deno.land/std@$STD_VERSION/fs/mod.ts";
*
* if (await readableFile("./foo.txt")) {
* await Deno.remove("./foo.txt");
* }
* ```
*
* Good:
* ```ts
* // Notice no use of readableFile
* try {
* await Deno.remove("./foo.txt");
* } catch (error) {
* if (!(error instanceof Deno.errors.NotFound)) {
* throw error;
* }
* // Do nothing...
* }
* ```
* @see https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
*/
export async function readableFile(filePath: string | URL): Promise<boolean> {
try {
return (await Deno.stat(filePath)).isFile;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return false;
}
throw error;
}
}

/**
* Test whether or not the given path is a readable file by checking with the file system.
*
* Note: do not use this function if performing a check before another operation on that file. Doing so creates a race condition. Instead, perform the actual file operation directly.
*
* Bad:
* ```ts
* import { readableFile } from "https://deno.land/std@$STD_VERSION/fs/mod.ts";
*
* if (await readableFile("./foo.txt")) {
martin-braun marked this conversation as resolved.
Show resolved Hide resolved
* await Deno.remove("./foo.txt");
* }
* ```
*
* Good:
* ```ts
* // Notice no use of readableFile
* try {
* await Deno.remove("./foo.txt");
* } catch (error) {
* if (!(error instanceof Deno.errors.NotFound)) {
* throw error;
* }
* // Do nothing...
* }
* ```
* @see https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
*/
export function readableFileSync(filePath: string | URL): boolean {
try {
return Deno.statSync(filePath).isFile;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return false;
}
throw error;
}
}
61 changes: 61 additions & 0 deletions fs/readable_file_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
import { assertEquals } from "../testing/asserts.ts";
import * as path from "../path/mod.ts";
import { readableFile, readableFileSync } from "./readable_file.ts";

const moduleDir = path.dirname(path.fromFileUrl(import.meta.url));
const testdataDir = path.resolve(moduleDir, "testdata");

Deno.test("[fs] readableFile", async function () {
assertEquals(
await readableFile(path.join(testdataDir, "not_exist_file.ts")),
false,
);
assertEquals(await readableFile(path.join(testdataDir, "0.ts")), true);
});

Deno.test("[fs] readableFileSync", function () {
assertEquals(readableFileSync(path.join(testdataDir, "not_exist_file.ts")), false);
assertEquals(readableFileSync(path.join(testdataDir, "0.ts")), true);
});

Deno.test("[fs] readableDir", async function () {
assertEquals(
await readableFile(path.join(testdataDir, "not_exist_directory")),
false,
);
assertEquals(await readableFile(testdataDir), false);
});

Deno.test("[fs] readableDirSync", function () {
assertEquals(
readableFileSync(path.join(testdataDir, "not_exist_directory")),
false,
);
assertEquals(readableFileSync(testdataDir), false);
});

Deno.test("[fs] readableFileLink", async function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(await readableFile(path.join(testdataDir, "0-link")), true);
});

Deno.test("[fs] readableFileLinkSync", function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(readableFileSync(path.join(testdataDir, "0-link")), true);
});

Deno.test("[fs] readableDirLink", async function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(await readableFile(path.join(testdataDir, "testdata-link")), false);
});

Deno.test("[fs] readableDirLinkSync", function () {
// TODO(axetroy): generate link file use Deno api instead of set a link file
// in repository
assertEquals(readableFileSync(path.join(testdataDir, "testdata-link")), false);
});

Loading