diff --git a/fs/exists.ts b/fs/exists.ts index 2c68ec6cfd5d..aa6334b43187 100644 --- a/fs/exists.ts +++ b/fs/exists.ts @@ -1,12 +1,20 @@ // 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 */ export async function exists(filePath: string): Promise { - return Deno.lstat(filePath) + return lstat(filePath) .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 { */ export function existsSync(filePath: string): boolean { try { - Deno.lstatSync(filePath); + lstatSync(filePath); return true; - } catch { - return false; + } catch (err) { + if (err instanceof DenoError) { + if (err.kind === ErrorKind.NotFound) { + return false; + } + } + throw err; } } diff --git a/fs/exists_test.ts b/fs/exists_test.ts index e65befa7846c..69c18d467e0b 100644 --- a/fs/exists_test.ts +++ b/fs/exists_test.ts @@ -46,3 +46,96 @@ test(async function existsLink(): Promise { // in repository assertEquals(await exists(path.join(testdataDir, "0-link.ts")), true); }); + +test(async function existsPermission(): Promise { + 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 +}); diff --git a/fs/testdata/exists.ts b/fs/testdata/exists.ts new file mode 100644 index 000000000000..aee8574d87dc --- /dev/null +++ b/fs/testdata/exists.ts @@ -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)) + }) + diff --git a/fs/testdata/exists_sync.ts b/fs/testdata/exists_sync.ts new file mode 100644 index 000000000000..70b2071c114f --- /dev/null +++ b/fs/testdata/exists_sync.ts @@ -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)) +} + +