summaryrefslogtreecommitdiff
path: root/std/fs
diff options
context:
space:
mode:
authorAxetroy <axetroy.dev@gmail.com>2019-12-18 18:12:36 +0800
committerRy Dahl <ry@tinyclouds.org>2019-12-18 05:12:36 -0500
commitbb24fb74ffe0bb35649e0adbb1473458c8abf71f (patch)
tree4eaf1b19f5e505b2cad2ea2cda5ad28cb2104f35 /std/fs
parent3115781e4316653ab3619e3d94bdbce01fca4ec2 (diff)
fix permission errors are swallowed by fs.emptyDir (#3501)
Diffstat (limited to 'std/fs')
-rw-r--r--std/fs/empty_dir.ts65
-rw-r--r--std/fs/empty_dir_test.ts113
-rw-r--r--std/fs/testdata/empty_dir.ts9
-rw-r--r--std/fs/testdata/empty_dir_sync.ts8
4 files changed, 172 insertions, 23 deletions
diff --git a/std/fs/empty_dir.ts b/std/fs/empty_dir.ts
index 81bc45839..ded02b7e4 100644
--- a/std/fs/empty_dir.ts
+++ b/std/fs/empty_dir.ts
@@ -1,25 +1,39 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+import { join } from "../path/mod.ts";
+const {
+ readDir,
+ readDirSync,
+ mkdir,
+ mkdirSync,
+ remove,
+ removeSync,
+ ErrorKind
+} = Deno;
/**
* Ensures that a directory is empty.
* Deletes directory contents if the directory is not empty.
* If the directory does not exist, it is created.
* The directory itself is not deleted.
+ * Requires the `--allow-read` and `--alow-write` flag.
*/
export async function emptyDir(dir: string): Promise<void> {
- let items: Deno.FileInfo[] = [];
try {
- items = await Deno.readDir(dir);
- } catch {
- // if not exist. then create it
- await Deno.mkdir(dir, true);
- return;
- }
- while (items.length) {
- const item = items.shift();
- if (item && item.name) {
- const fn = dir + "/" + item.name;
- await Deno.remove(fn, { recursive: true });
+ const items = await readDir(dir);
+
+ while (items.length) {
+ const item = items.shift();
+ if (item && item.name) {
+ const filepath = join(dir, item.name);
+ await remove(filepath, { recursive: true });
+ }
+ }
+ } catch (err) {
+ if ((err as Deno.DenoError<Deno.ErrorKind>).kind !== ErrorKind.NotFound) {
+ throw err;
}
+
+ // if not exist. then create it
+ await mkdir(dir, true);
}
}
@@ -28,21 +42,26 @@ export async function emptyDir(dir: string): Promise<void> {
* Deletes directory contents if the directory is not empty.
* If the directory does not exist, it is created.
* The directory itself is not deleted.
+ * Requires the `--allow-read` and `--alow-write` flag.
*/
export function emptyDirSync(dir: string): void {
- let items: Deno.FileInfo[] = [];
try {
- items = Deno.readDirSync(dir);
- } catch {
+ const items = readDirSync(dir);
+
+ // if directory already exist. then remove it's child item.
+ while (items.length) {
+ const item = items.shift();
+ if (item && item.name) {
+ const filepath = join(dir, item.name);
+ removeSync(filepath, { recursive: true });
+ }
+ }
+ } catch (err) {
+ if ((err as Deno.DenoError<Deno.ErrorKind>).kind !== ErrorKind.NotFound) {
+ throw err;
+ }
// if not exist. then create it
- Deno.mkdirSync(dir, true);
+ mkdirSync(dir, true);
return;
}
- while (items.length) {
- const item = items.shift();
- if (item && item.name) {
- const fn = dir + "/" + item.name;
- Deno.removeSync(fn, { recursive: true });
- }
- }
}
diff --git a/std/fs/empty_dir_test.ts b/std/fs/empty_dir_test.ts
index ac5b13476..d25461ce3 100644
--- a/std/fs/empty_dir_test.ts
+++ b/std/fs/empty_dir_test.ts
@@ -123,3 +123,116 @@ test(function emptyDirSyncIfItExist(): void {
Deno.removeSync(testDir, { recursive: true });
}
});
+
+test(async function emptyDirPermission(): Promise<void> {
+ interface Scenes {
+ read: boolean; // --allow-read
+ write: boolean; // --allow-write
+ async: boolean;
+ output: string;
+ }
+
+ const testfolder = path.join(testdataDir, "testfolder");
+
+ await Deno.mkdir(testfolder);
+
+ await Deno.writeFile(
+ path.join(testfolder, "child.txt"),
+ new TextEncoder().encode("hello world")
+ );
+
+ const scenes: Scenes[] = [
+ // 1
+ {
+ read: false,
+ write: false,
+ async: true,
+ output: "run again with the --allow-read flag"
+ },
+ {
+ read: false,
+ write: false,
+ async: false,
+ output: "run again with the --allow-read flag"
+ },
+ // 2
+ {
+ read: true,
+ write: false,
+ async: true,
+ output: "run again with the --allow-write flag"
+ },
+ {
+ read: true,
+ write: false,
+ async: false,
+ output: "run again with the --allow-write flag"
+ },
+ // 3
+ {
+ read: false,
+ write: true,
+ async: true,
+ output: "run again with the --allow-read flag"
+ },
+ {
+ read: false,
+ write: true,
+ async: false,
+ output: "run again with the --allow-read flag"
+ },
+ // 4
+ {
+ read: true,
+ write: true,
+ async: true,
+ output: "success"
+ },
+ {
+ read: true,
+ write: true,
+ async: false,
+ output: "success"
+ }
+ ];
+
+ try {
+ for (const s of scenes) {
+ console.log(
+ `test ${s.async ? "emptyDir" : "emptyDirSync"}("testdata/testfolder") ${
+ s.read ? "with" : "without"
+ } --allow-read & ${s.write ? "with" : "without"} --allow-write`
+ );
+
+ const args = [Deno.execPath(), "run"];
+
+ if (s.read) {
+ args.push("--allow-read");
+ }
+
+ if (s.write) {
+ args.push("--allow-write");
+ }
+
+ args.push(
+ path.join(testdataDir, s.async ? "empty_dir.ts" : "empty_dir_sync.ts")
+ );
+ args.push("testfolder");
+
+ const { stdout } = Deno.run({
+ stdout: "piped",
+ cwd: testdataDir,
+ args: args
+ });
+
+ const output = await Deno.readAll(stdout);
+
+ assertEquals(new TextDecoder().decode(output), s.output);
+ }
+ } catch (err) {
+ await Deno.remove(testfolder, { recursive: true });
+ throw err;
+ }
+
+ // done
+});
diff --git a/std/fs/testdata/empty_dir.ts b/std/fs/testdata/empty_dir.ts
new file mode 100644
index 000000000..6147679da
--- /dev/null
+++ b/std/fs/testdata/empty_dir.ts
@@ -0,0 +1,9 @@
+import { emptyDir } from "../empty_dir.ts";
+
+emptyDir(Deno.args[1])
+ .then(() => {
+ Deno.stdout.write(new TextEncoder().encode("success"))
+ })
+ .catch((err) => {
+ Deno.stdout.write(new TextEncoder().encode(err.message))
+ }) \ No newline at end of file
diff --git a/std/fs/testdata/empty_dir_sync.ts b/std/fs/testdata/empty_dir_sync.ts
new file mode 100644
index 000000000..3c0eb9031
--- /dev/null
+++ b/std/fs/testdata/empty_dir_sync.ts
@@ -0,0 +1,8 @@
+import { emptyDirSync } from "../empty_dir.ts";
+
+try {
+ emptyDirSync(Deno.args[1])
+ Deno.stdout.write(new TextEncoder().encode("success"))
+} catch (err) {
+ Deno.stdout.write(new TextEncoder().encode(err.message))
+} \ No newline at end of file