1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 16:19:12 -05:00

fix permission errors are swallowed by fs.exists (#3493)

This commit is contained in:
Axetroy 2019-12-13 22:47:09 +08:00 committed by Ry Dahl
parent df7d8288d9
commit 8cf8a29d35
4 changed files with 132 additions and 6 deletions

View file

@ -1,12 +1,20 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
const { lstat, lstatSync, DenoError, ErrorKind } = Deno;
/** /**
* Test whether or not the given path exists by checking with the file system * Test whether or not the given path exists by checking with the file system
*/ */
export async function exists(filePath: string): Promise<boolean> { export async function exists(filePath: string): Promise<boolean> {
return Deno.lstat(filePath) return lstat(filePath)
.then((): boolean => true) .then((): boolean => true)
.catch((): boolean => false); .catch((err: Error): boolean => {
if (err instanceof DenoError) {
if (err.kind === ErrorKind.NotFound) {
return false;
}
}
throw err;
});
} }
/** /**
@ -14,9 +22,14 @@ export async function exists(filePath: string): Promise<boolean> {
*/ */
export function existsSync(filePath: string): boolean { export function existsSync(filePath: string): boolean {
try { try {
Deno.lstatSync(filePath); lstatSync(filePath);
return true; return true;
} catch { } catch (err) {
if (err instanceof DenoError) {
if (err.kind === ErrorKind.NotFound) {
return false; return false;
} }
} }
throw err;
}
}

View file

@ -46,3 +46,96 @@ test(async function existsLink(): Promise<void> {
// in repository // in repository
assertEquals(await exists(path.join(testdataDir, "0-link.ts")), true); assertEquals(await exists(path.join(testdataDir, "0-link.ts")), true);
}); });
test(async function existsPermission(): Promise<void> {
interface Scenes {
read: boolean; // --allow-read
async: boolean;
output: string;
file: string; // target file to run
}
const scenes: Scenes[] = [
// 1
{
read: false,
async: true,
output: "run again with the --allow-read flag",
file: "0.ts"
},
{
read: false,
async: false,
output: "run again with the --allow-read flag",
file: "0.ts"
},
// 2
{
read: true,
async: true,
output: "exist",
file: "0.ts"
},
{
read: true,
async: false,
output: "exist",
file: "0.ts"
},
// 3
{
read: false,
async: true,
output: "run again with the --allow-read flag",
file: "no_exist_file_for_test.ts"
},
{
read: false,
async: false,
output: "run again with the --allow-read flag",
file: "no_exist_file_for_test.ts"
},
// 4
{
read: true,
async: true,
output: "not exist",
file: "no_exist_file_for_test.ts"
},
{
read: true,
async: false,
output: "not exist",
file: "no_exist_file_for_test.ts"
}
];
for (const s of scenes) {
console.log(
`test ${s.async ? "exists" : "existsSync"}("testdata/${s.file}") ${
s.read ? "with" : "without"
} --allow-read`
);
const args = [Deno.execPath(), "run"];
if (s.read) {
args.push("--allow-read");
}
args.push(path.join(testdataDir, s.async ? "exists.ts" : "exists_sync.ts"));
args.push(s.file);
const { stdout } = Deno.run({
stdout: "piped",
cwd: testdataDir,
args: args
});
const output = await Deno.readAll(stdout);
assertEquals(new TextDecoder().decode(output), s.output);
}
// done
});

10
std/fs/testdata/exists.ts vendored Normal file
View file

@ -0,0 +1,10 @@
import { exists } from "../exists.ts";
exists(Deno.args[1])
.then(isExist => {
Deno.stdout.write(new TextEncoder().encode(isExist ? 'exist' :'not exist'))
})
.catch((err) => {
Deno.stdout.write(new TextEncoder().encode(err.message))
})

10
std/fs/testdata/exists_sync.ts vendored Normal file
View file

@ -0,0 +1,10 @@
import { existsSync } from "../exists.ts";
try {
const isExist = existsSync(Deno.args[1])
Deno.stdout.write(new TextEncoder().encode(isExist ? 'exist' :'not exist'))
} catch (err) {
Deno.stdout.write(new TextEncoder().encode(err.message))
}