mirror of
https://github.com/denoland/deno
synced 2024-11-05 18:45:24 +00:00
fix permission errors are swallowed by fs.copy() (#3504)
This commit is contained in:
parent
1c09cc63c8
commit
ef30d376db
3 changed files with 70 additions and 62 deletions
|
@ -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)
|
||||
);
|
||||
let destStat: Deno.FileInfo | 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.`);
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue