diff options
author | Axetroy <axetroy.dev@gmail.com> | 2019-12-18 22:45:19 +0800 |
---|---|---|
committer | Ry Dahl <ry@tinyclouds.org> | 2019-12-18 09:45:19 -0500 |
commit | ef30d376db94bda24ed31947a1cc264b827705dc (patch) | |
tree | aba58a06c797efd513a1a83ba056487e18674d6f | |
parent | 1c09cc63c8b9c33842ee302c93aebc6593be8b15 (diff) |
fix permission errors are swallowed by fs.copy() (#3504)
-rw-r--r-- | std/fs/copy.ts | 52 | ||||
-rw-r--r-- | std/fs/ensure_dir.ts | 40 | ||||
-rw-r--r-- | std/fs/ensure_file.ts | 42 |
3 files changed, 71 insertions, 63 deletions
diff --git a/std/fs/copy.ts b/std/fs/copy.ts index f5e7f5078..783597882 100644 --- a/std/fs/copy.ts +++ b/std/fs/copy.ts @@ -23,21 +23,25 @@ async function ensureValidCopy( options: CopyOptions, isCopyFolder = false ): Promise<Deno.FileInfo> { - const destStat: Deno.FileInfo | null = await Deno.lstat(dest).catch( - (): Promise<null> => Promise.resolve(null) - ); - - if (destStat) { - if (isCopyFolder && !destStat.isDirectory()) { - throw new Error( - `Cannot overwrite non-directory '${dest}' with directory '${src}'.` - ); - } - if (!options.overwrite) { - throw new Error(`'${dest}' already exists.`); + let destStat: Deno.FileInfo | null; + + try { + destStat = await Deno.lstat(dest); + } catch (err) { + if (err instanceof Deno.DenoError && err.kind == Deno.ErrorKind.NotFound) { + return; } } + if (isCopyFolder && !destStat.isDirectory()) { + throw new Error( + `Cannot overwrite non-directory '${dest}' with directory '${src}'.` + ); + } + if (!options.overwrite) { + throw new Error(`'${dest}' already exists.`); + } + return destStat!; } @@ -51,19 +55,19 @@ function ensureValidCopySync( try { destStat = Deno.lstatSync(dest); - } catch { - // ignore error + } catch (err) { + if (err instanceof Deno.DenoError && err.kind == Deno.ErrorKind.NotFound) { + return; + } } - if (destStat!) { - if (isCopyFolder && !destStat!.isDirectory()) { - throw new Error( - `Cannot overwrite non-directory '${dest}' with directory '${src}'.` - ); - } - if (!options.overwrite) { - throw new Error(`'${dest}' already exists.`); - } + if (isCopyFolder && !destStat!.isDirectory()) { + throw new Error( + `Cannot overwrite non-directory '${dest}' with directory '${src}'.` + ); + } + if (!options.overwrite) { + throw new Error(`'${dest}' already exists.`); } return destStat!; @@ -186,6 +190,7 @@ function copyDirSync(src: string, dest: string, options: CopyOptions): void { /** * Copy a file or directory. The directory can have contents. Like `cp -r`. + * Requires the `--allow-read` and `--alow-write` flag. * @param src the file/directory path. * Note that if `src` is a directory it will copy everything inside * of this directory, not the entire directory itself @@ -224,6 +229,7 @@ export async function copy( /** * Copy a file or directory. The directory can have contents. Like `cp -r`. + * Requires the `--allow-read` and `--alow-write` flag. * @param src the file/directory path. * Note that if `src` is a directory it will copy everything inside * of this directory, not the entire directory itself diff --git a/std/fs/ensure_dir.ts b/std/fs/ensure_dir.ts index dfc02f35c..de0cba333 100644 --- a/std/fs/ensure_dir.ts +++ b/std/fs/ensure_dir.ts @@ -1,49 +1,49 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { getFileInfoType } from "./utils.ts"; +const { lstat, lstatSync, mkdir, mkdirSync, ErrorKind } = Deno; + /** * Ensures that the directory exists. * If the directory structure does not exist, it is created. Like mkdir -p. + * Requires the `--allow-read` and `--alow-write` flag. */ export async function ensureDir(dir: string): Promise<void> { - let pathExists = false; try { - // if dir exists - const stat = await Deno.stat(dir); - pathExists = true; - if (!stat.isDirectory()) { + const fileInfo = await lstat(dir); + if (!fileInfo.isDirectory()) { throw new Error( - `Ensure path exists, expected 'dir', got '${getFileInfoType(stat)}'` + `Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'` ); } } catch (err) { - if (pathExists) { - throw err; + if (err instanceof Deno.DenoError && err.kind === ErrorKind.NotFound) { + // if dir not exists. then create it. + await mkdir(dir, true); + return; } - // if dir not exists. then create it. - await Deno.mkdir(dir, true); + throw err; } } /** * Ensures that the directory exists. * If the directory structure does not exist, it is created. Like mkdir -p. + * Requires the `--allow-read` and `--alow-write` flag. */ export function ensureDirSync(dir: string): void { - let pathExists = false; try { - // if dir exists - const stat = Deno.statSync(dir); - pathExists = true; - if (!stat.isDirectory()) { + const fileInfo = lstatSync(dir); + if (!fileInfo.isDirectory()) { throw new Error( - `Ensure path exists, expected 'dir', got '${getFileInfoType(stat)}'` + `Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'` ); } } catch (err) { - if (pathExists) { - throw err; + if (err instanceof Deno.DenoError && err.kind == ErrorKind.NotFound) { + // if dir not exists. then create it. + mkdirSync(dir, true); + return; } - // if dir not exists. then create it. - Deno.mkdirSync(dir, true); + throw err; } } diff --git a/std/fs/ensure_file.ts b/std/fs/ensure_file.ts index 0d6d7fbc4..e46d7b5f9 100644 --- a/std/fs/ensure_file.ts +++ b/std/fs/ensure_file.ts @@ -2,6 +2,7 @@ import * as path from "../path/mod.ts"; import { ensureDir, ensureDirSync } from "./ensure_dir.ts"; import { getFileInfoType } from "./utils.ts"; +const { lstat, lstatSync, writeFile, writeFileSync, ErrorKind } = Deno; /** * Ensures that the file exists. @@ -9,27 +10,28 @@ import { getFileInfoType } from "./utils.ts"; * exist. * these directories are created. If the file already exists, * it is NOTMODIFIED. + * Requires the `--allow-read` and `--alow-write` flag. */ export async function ensureFile(filePath: string): Promise<void> { - let pathExists = false; try { // if file exists - const stat = await Deno.lstat(filePath); - pathExists = true; + const stat = await lstat(filePath); if (!stat.isFile()) { throw new Error( `Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'` ); } } catch (err) { - if (pathExists) { - throw err; - } // if file not exists - // ensure dir exists - await ensureDir(path.dirname(filePath)); - // create file - await Deno.writeFile(filePath, new Uint8Array()); + if (err instanceof Deno.DenoError && err.kind === ErrorKind.NotFound) { + // ensure dir exists + await ensureDir(path.dirname(filePath)); + // create file + await writeFile(filePath, new Uint8Array()); + return; + } + + throw err; } } @@ -39,26 +41,26 @@ export async function ensureFile(filePath: string): Promise<void> { * exist, * these directories are created. If the file already exists, * it is NOT MODIFIED. + * Requires the `--allow-read` and `--alow-write` flag. */ export function ensureFileSync(filePath: string): void { - let pathExists = false; try { // if file exists - const stat = Deno.statSync(filePath); - pathExists = true; + const stat = lstatSync(filePath); if (!stat.isFile()) { throw new Error( `Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'` ); } } catch (err) { - if (pathExists) { - throw err; - } // if file not exists - // ensure dir exists - ensureDirSync(path.dirname(filePath)); - // create file - Deno.writeFileSync(filePath, new Uint8Array()); + if (err instanceof Deno.DenoError && err.kind === ErrorKind.NotFound) { + // ensure dir exists + ensureDirSync(path.dirname(filePath)); + // create file + writeFileSync(filePath, new Uint8Array()); + return; + } + throw err; } } |