mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
feat: URL support in Deno filesystem methods (#5990)
This commit is contained in:
parent
813210d433
commit
818a801092
28 changed files with 741 additions and 66 deletions
|
@ -21,7 +21,7 @@ import {
|
|||
export { OpenOptions } from "./ops/fs/open.ts";
|
||||
|
||||
export function openSync(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
options: OpenOptions = { read: true }
|
||||
): File {
|
||||
checkOpenOptions(options);
|
||||
|
@ -30,7 +30,7 @@ export function openSync(
|
|||
}
|
||||
|
||||
export async function open(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
options: OpenOptions = { read: true }
|
||||
): Promise<File> {
|
||||
checkOpenOptions(options);
|
||||
|
@ -38,7 +38,7 @@ export async function open(
|
|||
return new File(rid);
|
||||
}
|
||||
|
||||
export function createSync(path: string): File {
|
||||
export function createSync(path: string | URL): File {
|
||||
return openSync(path, {
|
||||
read: true,
|
||||
write: true,
|
||||
|
@ -47,7 +47,7 @@ export function createSync(path: string): File {
|
|||
});
|
||||
}
|
||||
|
||||
export function create(path: string): Promise<File> {
|
||||
export function create(path: string | URL): Promise<File> {
|
||||
return open(path, {
|
||||
read: true,
|
||||
write: true,
|
||||
|
|
78
cli/js/lib.deno.ns.d.ts
vendored
78
cli/js/lib.deno.ns.d.ts
vendored
|
@ -419,7 +419,7 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-read` and/or `allow-write` permissions depending on options.
|
||||
*/
|
||||
export function openSync(path: string, options?: OpenOptions): File;
|
||||
export function openSync(path: string | URL, options?: OpenOptions): File;
|
||||
|
||||
/** Open a file and resolve to an instance of `Deno.File`. The
|
||||
* file does not need to previously exist if using the `create` or `createNew`
|
||||
|
@ -434,7 +434,10 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-read` and/or `allow-write` permissions depending on options.
|
||||
*/
|
||||
export function open(path: string, options?: OpenOptions): Promise<File>;
|
||||
export function open(
|
||||
path: string | URL,
|
||||
options?: OpenOptions
|
||||
): Promise<File>;
|
||||
|
||||
/** Creates a file if none exists or truncates an existing file and returns
|
||||
* an instance of `Deno.File`.
|
||||
|
@ -445,7 +448,7 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-read` and `allow-write` permissions.
|
||||
*/
|
||||
export function createSync(path: string): File;
|
||||
export function createSync(path: string | URL): File;
|
||||
|
||||
/** Creates a file if none exists or truncates an existing file and resolves to
|
||||
* an instance of `Deno.File`.
|
||||
|
@ -456,7 +459,7 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-read` and `allow-write` permissions.
|
||||
*/
|
||||
export function create(path: string): Promise<File>;
|
||||
export function create(path: string | URL): Promise<File>;
|
||||
|
||||
/** Synchronously read from a resource ID (`rid`) into an array buffer (`buffer`).
|
||||
*
|
||||
|
@ -890,7 +893,7 @@ declare namespace Deno {
|
|||
* Defaults to throwing error if the directory already exists.
|
||||
*
|
||||
* Requires `allow-write` permission. */
|
||||
export function mkdirSync(path: string, options?: MkdirOptions): void;
|
||||
export function mkdirSync(path: string | URL, options?: MkdirOptions): void;
|
||||
|
||||
/** Creates a new directory with the specified path.
|
||||
*
|
||||
|
@ -903,7 +906,10 @@ declare namespace Deno {
|
|||
* Defaults to throwing error if the directory already exists.
|
||||
*
|
||||
* Requires `allow-write` permission. */
|
||||
export function mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
||||
export function mkdir(
|
||||
path: string | URL,
|
||||
options?: MkdirOptions
|
||||
): Promise<void>;
|
||||
|
||||
export interface MakeTempOptions {
|
||||
/** Directory where the temporary directory should be created (defaults to
|
||||
|
@ -1011,7 +1017,7 @@ declare namespace Deno {
|
|||
* NOTE: This API currently throws on Windows
|
||||
*
|
||||
* Requires `allow-write` permission. */
|
||||
export function chmodSync(path: string, mode: number): void;
|
||||
export function chmodSync(path: string | URL, mode: number): void;
|
||||
|
||||
/** Changes the permission of a specific file/directory of specified path.
|
||||
* Ignores the process's umask.
|
||||
|
@ -1041,7 +1047,7 @@ declare namespace Deno {
|
|||
* NOTE: This API currently throws on Windows
|
||||
*
|
||||
* Requires `allow-write` permission. */
|
||||
export function chmod(path: string, mode: number): Promise<void>;
|
||||
export function chmod(path: string | URL, mode: number): Promise<void>;
|
||||
|
||||
/** Synchronously change owner of a regular file or directory. This functionality
|
||||
* is not available on Windows.
|
||||
|
@ -1058,7 +1064,7 @@ declare namespace Deno {
|
|||
* @param uid user id (UID) of the new owner
|
||||
* @param gid group id (GID) of the new owner
|
||||
*/
|
||||
export function chownSync(path: string, uid: number, gid: number): void;
|
||||
export function chownSync(path: string | URL, uid: number, gid: number): void;
|
||||
|
||||
/** Change owner of a regular file or directory. This functionality
|
||||
* is not available on Windows.
|
||||
|
@ -1075,7 +1081,11 @@ declare namespace Deno {
|
|||
* @param uid user id (UID) of the new owner
|
||||
* @param gid group id (GID) of the new owner
|
||||
*/
|
||||
export function chown(path: string, uid: number, gid: number): Promise<void>;
|
||||
export function chown(
|
||||
path: string | URL,
|
||||
uid: number,
|
||||
gid: number
|
||||
): Promise<void>;
|
||||
|
||||
export interface RemoveOptions {
|
||||
/** Defaults to `false`. If set to `true`, path will be removed even if
|
||||
|
@ -1094,7 +1104,7 @@ declare namespace Deno {
|
|||
* directory and the `recursive` option isn't set to `true`.
|
||||
*
|
||||
* Requires `allow-write` permission. */
|
||||
export function removeSync(path: string, options?: RemoveOptions): void;
|
||||
export function removeSync(path: string | URL, options?: RemoveOptions): void;
|
||||
|
||||
/** Removes the named file or directory.
|
||||
*
|
||||
|
@ -1107,7 +1117,10 @@ declare namespace Deno {
|
|||
* directory and the `recursive` option isn't set to `true`.
|
||||
*
|
||||
* Requires `allow-write` permission. */
|
||||
export function remove(path: string, options?: RemoveOptions): Promise<void>;
|
||||
export function remove(
|
||||
path: string | URL,
|
||||
options?: RemoveOptions
|
||||
): Promise<void>;
|
||||
|
||||
/** Synchronously renames (moves) `oldpath` to `newpath`. Paths may be files or
|
||||
* directories. If `newpath` already exists and is not a directory,
|
||||
|
@ -1152,7 +1165,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readTextFileSync(path: string): string;
|
||||
export function readTextFileSync(path: string | URL): string;
|
||||
|
||||
/** Asynchronously reads and returns the entire contents of a file as a utf8
|
||||
* encoded string. Reading a directory returns an empty data array.
|
||||
|
@ -1163,7 +1176,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readTextFile(path: string): Promise<string>;
|
||||
export function readTextFile(path: string | URL): Promise<string>;
|
||||
|
||||
/** Synchronously reads and returns the entire contents of a file as an array
|
||||
* of bytes. `TextDecoder` can be used to transform the bytes to string if
|
||||
|
@ -1176,7 +1189,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readFileSync(path: string): Uint8Array;
|
||||
export function readFileSync(path: string | URL): Uint8Array;
|
||||
|
||||
/** Reads and resolves to the entire contents of a file as an array of bytes.
|
||||
* `TextDecoder` can be used to transform the bytes to string if required.
|
||||
|
@ -1189,7 +1202,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readFile(path: string): Promise<Uint8Array>;
|
||||
export function readFile(path: string | URL): Promise<Uint8Array>;
|
||||
|
||||
/** A FileInfo describes a file and is returned by `stat`, `lstat`,
|
||||
* `statSync`, `lstatSync`. */
|
||||
|
@ -1307,7 +1320,7 @@ declare namespace Deno {
|
|||
* Throws error if `path` is not a directory.
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readDirSync(path: string): Iterable<DirEntry>;
|
||||
export function readDirSync(path: string | URL): Iterable<DirEntry>;
|
||||
|
||||
/** Reads the directory given by `path` and returns an async iterable of
|
||||
* `Deno.DirEntry`.
|
||||
|
@ -1321,7 +1334,7 @@ declare namespace Deno {
|
|||
* Throws error if `path` is not a directory.
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readDir(path: string): AsyncIterable<DirEntry>;
|
||||
export function readDir(path: string | URL): AsyncIterable<DirEntry>;
|
||||
|
||||
/** Synchronously copies the contents and permissions of one file to another
|
||||
* specified path, by default creating a new file if needed, else overwriting.
|
||||
|
@ -1333,7 +1346,10 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-read` permission on fromPath.
|
||||
* Requires `allow-write` permission on toPath. */
|
||||
export function copyFileSync(fromPath: string, toPath: string): void;
|
||||
export function copyFileSync(
|
||||
fromPath: string | URL,
|
||||
toPath: string | URL
|
||||
): void;
|
||||
|
||||
/** Copies the contents and permissions of one file to another specified path,
|
||||
* by default creating a new file if needed, else overwriting. Fails if target
|
||||
|
@ -1345,7 +1361,10 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-read` permission on fromPath.
|
||||
* Requires `allow-write` permission on toPath. */
|
||||
export function copyFile(fromPath: string, toPath: string): Promise<void>;
|
||||
export function copyFile(
|
||||
fromPath: string | URL,
|
||||
toPath: string | URL
|
||||
): Promise<void>;
|
||||
|
||||
/** Returns the full path destination of the named symbolic link.
|
||||
*
|
||||
|
@ -1382,7 +1401,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function lstat(path: string): Promise<FileInfo>;
|
||||
export function lstat(path: string | URL): Promise<FileInfo>;
|
||||
|
||||
/** Synchronously returns a `Deno.FileInfo` for the specified `path`. If
|
||||
* `path` is a symlink, information for the symlink will be returned instead of
|
||||
|
@ -1394,7 +1413,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function lstatSync(path: string): FileInfo;
|
||||
export function lstatSync(path: string | URL): FileInfo;
|
||||
|
||||
/** Resolves to a `Deno.FileInfo` for the specified `path`. Will always
|
||||
* follow symlinks.
|
||||
|
@ -1406,7 +1425,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function stat(path: string): Promise<FileInfo>;
|
||||
export function stat(path: string | URL): Promise<FileInfo>;
|
||||
|
||||
/** Synchronously returns a `Deno.FileInfo` for the specified `path`. Will
|
||||
* always follow symlinks.
|
||||
|
@ -1418,7 +1437,7 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function statSync(path: string): FileInfo;
|
||||
export function statSync(path: string | URL): FileInfo;
|
||||
|
||||
/** Options for writing to a file. */
|
||||
export interface WriteFileOptions {
|
||||
|
@ -1448,7 +1467,7 @@ declare namespace Deno {
|
|||
* `false`.
|
||||
*/
|
||||
export function writeFileSync(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
data: Uint8Array,
|
||||
options?: WriteFileOptions
|
||||
): void;
|
||||
|
@ -1468,7 +1487,7 @@ declare namespace Deno {
|
|||
* Requires `allow-write` permission, and `allow-read` if `options.create` is `false`.
|
||||
*/
|
||||
export function writeFile(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
data: Uint8Array,
|
||||
options?: WriteFileOptions
|
||||
): Promise<void>;
|
||||
|
@ -1482,7 +1501,7 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-write` permission, and `allow-read` if `options.create` is `false`.
|
||||
*/
|
||||
export function writeTextFileSync(path: string, data: string): void;
|
||||
export function writeTextFileSync(path: string | URL, data: string): void;
|
||||
|
||||
/** Asynchronously write string `data` to the given `path`, by default creating a new file if needed,
|
||||
* else overwriting.
|
||||
|
@ -1493,7 +1512,10 @@ declare namespace Deno {
|
|||
*
|
||||
* Requires `allow-write` permission, and `allow-read` if `options.create` is `false`.
|
||||
*/
|
||||
export function writeTextFile(path: string, data: string): Promise<void>;
|
||||
export function writeTextFile(
|
||||
path: string | URL,
|
||||
data: string
|
||||
): Promise<void>;
|
||||
|
||||
/** Synchronously truncates or extends the specified file, to reach the
|
||||
* specified `len`. If `len` is not specified then the entire file contents
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export function chmodSync(path: string, mode: number): void {
|
||||
export function chmodSync(path: string | URL, mode: number): void {
|
||||
path = pathFromURL(path);
|
||||
sendSync("op_chmod", { path, mode });
|
||||
}
|
||||
|
||||
export async function chmod(path: string, mode: number): Promise<void> {
|
||||
export async function chmod(path: string | URL, mode: number): Promise<void> {
|
||||
path = pathFromURL(path);
|
||||
await sendAsync("op_chmod", { path, mode });
|
||||
}
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export function chownSync(path: string, uid: number, gid: number): void {
|
||||
export function chownSync(path: string | URL, uid: number, gid: number): void {
|
||||
path = pathFromURL(path);
|
||||
sendSync("op_chown", { path, uid, gid });
|
||||
}
|
||||
|
||||
export async function chown(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
uid: number,
|
||||
gid: number
|
||||
): Promise<void> {
|
||||
path = pathFromURL(path);
|
||||
await sendAsync("op_chown", { path, uid, gid });
|
||||
}
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export function copyFileSync(
|
||||
fromPath: string | URL,
|
||||
toPath: string | URL
|
||||
): void {
|
||||
fromPath = pathFromURL(fromPath);
|
||||
toPath = pathFromURL(toPath);
|
||||
|
||||
export function copyFileSync(fromPath: string, toPath: string): void {
|
||||
sendSync("op_copy_file", { from: fromPath, to: toPath });
|
||||
}
|
||||
|
||||
export async function copyFile(
|
||||
fromPath: string,
|
||||
toPath: string
|
||||
fromPath: string | URL,
|
||||
toPath: string | URL
|
||||
): Promise<void> {
|
||||
fromPath = pathFromURL(fromPath);
|
||||
toPath = pathFromURL(toPath);
|
||||
|
||||
await sendAsync("op_copy_file", { from: fromPath, to: toPath });
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export interface OpenOptions {
|
||||
read?: boolean;
|
||||
|
@ -15,13 +16,18 @@ export interface OpenOptions {
|
|||
mode?: number;
|
||||
}
|
||||
|
||||
export function openSync(path: string, options: OpenOptions): number {
|
||||
export function openSync(path: string | URL, options: OpenOptions): number {
|
||||
const mode: number | undefined = options?.mode;
|
||||
path = pathFromURL(path);
|
||||
return sendSync("op_open", { path, options, mode });
|
||||
}
|
||||
|
||||
export function open(path: string, options: OpenOptions): Promise<number> {
|
||||
export function open(
|
||||
path: string | URL,
|
||||
options: OpenOptions
|
||||
): Promise<number> {
|
||||
const mode: number | undefined = options?.mode;
|
||||
path = pathFromURL(path);
|
||||
return sendAsync("op_open", {
|
||||
path,
|
||||
options,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export interface DirEntry {
|
||||
name: string;
|
||||
|
@ -16,11 +17,13 @@ function res(response: ReadDirResponse): DirEntry[] {
|
|||
return response.entries;
|
||||
}
|
||||
|
||||
export function readDirSync(path: string): Iterable<DirEntry> {
|
||||
export function readDirSync(path: string | URL): Iterable<DirEntry> {
|
||||
path = pathFromURL(path);
|
||||
return res(sendSync("op_read_dir", { path }))[Symbol.iterator]();
|
||||
}
|
||||
|
||||
export function readDir(path: string): AsyncIterable<DirEntry> {
|
||||
export function readDir(path: string | URL): AsyncIterable<DirEntry> {
|
||||
path = pathFromURL(path);
|
||||
const array = sendAsync("op_read_dir", { path }).then(res);
|
||||
return {
|
||||
async *[Symbol.asyncIterator](): AsyncIterableIterator<DirEntry> {
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export interface RemoveOptions {
|
||||
recursive?: boolean;
|
||||
}
|
||||
|
||||
export function removeSync(path: string, options: RemoveOptions = {}): void {
|
||||
export function removeSync(
|
||||
path: string | URL,
|
||||
options: RemoveOptions = {}
|
||||
): void {
|
||||
path = pathFromURL(path);
|
||||
sendSync("op_remove", { path, recursive: !!options.recursive });
|
||||
}
|
||||
|
||||
export async function remove(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
options: RemoveOptions = {}
|
||||
): Promise<void> {
|
||||
path = pathFromURL(path);
|
||||
await sendAsync("op_remove", { path, recursive: !!options.recursive });
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { sendSync, sendAsync } from "../dispatch_json.ts";
|
||||
import { build } from "../../build.ts";
|
||||
import { pathFromURL } from "../../util.ts";
|
||||
|
||||
export interface FileInfo {
|
||||
size: number;
|
||||
|
@ -65,7 +66,8 @@ export function parseFileInfo(response: StatResponse): FileInfo {
|
|||
};
|
||||
}
|
||||
|
||||
export async function lstat(path: string): Promise<FileInfo> {
|
||||
export async function lstat(path: string | URL): Promise<FileInfo> {
|
||||
path = pathFromURL(path);
|
||||
const res = (await sendAsync("op_stat", {
|
||||
path,
|
||||
lstat: true,
|
||||
|
@ -73,7 +75,8 @@ export async function lstat(path: string): Promise<FileInfo> {
|
|||
return parseFileInfo(res);
|
||||
}
|
||||
|
||||
export function lstatSync(path: string): FileInfo {
|
||||
export function lstatSync(path: string | URL): FileInfo {
|
||||
path = pathFromURL(path);
|
||||
const res = sendSync("op_stat", {
|
||||
path,
|
||||
lstat: true,
|
||||
|
@ -81,7 +84,8 @@ export function lstatSync(path: string): FileInfo {
|
|||
return parseFileInfo(res);
|
||||
}
|
||||
|
||||
export async function stat(path: string): Promise<FileInfo> {
|
||||
export async function stat(path: string | URL): Promise<FileInfo> {
|
||||
path = pathFromURL(path);
|
||||
const res = (await sendAsync("op_stat", {
|
||||
path,
|
||||
lstat: false,
|
||||
|
@ -89,7 +93,8 @@ export async function stat(path: string): Promise<FileInfo> {
|
|||
return parseFileInfo(res);
|
||||
}
|
||||
|
||||
export function statSync(path: string): FileInfo {
|
||||
export function statSync(path: string | URL): FileInfo {
|
||||
path = pathFromURL(path);
|
||||
const res = sendSync("op_stat", {
|
||||
path,
|
||||
lstat: false,
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
import { open, openSync } from "./files.ts";
|
||||
import { readAll, readAllSync } from "./buffer.ts";
|
||||
|
||||
export function readFileSync(path: string): Uint8Array {
|
||||
export function readFileSync(path: string | URL): Uint8Array {
|
||||
const file = openSync(path);
|
||||
const contents = readAllSync(file);
|
||||
file.close();
|
||||
return contents;
|
||||
}
|
||||
|
||||
export async function readFile(path: string): Promise<Uint8Array> {
|
||||
export async function readFile(path: string | URL): Promise<Uint8Array> {
|
||||
const file = await open(path);
|
||||
const contents = await readAll(file);
|
||||
file.close();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { open, openSync } from "./files.ts";
|
||||
import { readAll, readAllSync } from "./buffer.ts";
|
||||
|
||||
export function readTextFileSync(path: string): string {
|
||||
export function readTextFileSync(path: string | URL): string {
|
||||
const decoder = new TextDecoder();
|
||||
const file = openSync(path);
|
||||
const content = readAllSync(file);
|
||||
|
@ -9,7 +9,7 @@ export function readTextFileSync(path: string): string {
|
|||
return decoder.decode(content);
|
||||
}
|
||||
|
||||
export async function readTextFile(path: string): Promise<string> {
|
||||
export async function readTextFile(path: string | URL): Promise<string> {
|
||||
const decoder = new TextDecoder();
|
||||
const file = await open(path);
|
||||
const content = await readAll(file);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { build } from "./build.ts";
|
||||
import { exposeForTest } from "./internals.ts";
|
||||
|
||||
let logDebug = false;
|
||||
let logSource = "JS";
|
||||
|
@ -78,3 +80,49 @@ export function immutableDefine(
|
|||
writable: false,
|
||||
});
|
||||
}
|
||||
|
||||
function pathFromURLWin32(url: URL): string {
|
||||
if (url.hostname !== "") {
|
||||
//TODO(actual-size) Node adds a punycode decoding step, we should consider adding this
|
||||
return `\\\\${url.hostname}${url.pathname}`;
|
||||
}
|
||||
|
||||
const validPath = /^\/(?<driveLetter>[A-Za-z]):\//;
|
||||
const matches = validPath.exec(url.pathname);
|
||||
|
||||
if (!matches?.groups?.driveLetter) {
|
||||
throw new TypeError("A URL with the file schema must be absolute.");
|
||||
}
|
||||
|
||||
const pathname = url.pathname.replace(/\//g, "\\");
|
||||
// we don't want a leading slash on an absolute path in Windows
|
||||
return pathname.slice(1);
|
||||
}
|
||||
|
||||
function pathFromURLPosix(url: URL): string {
|
||||
if (url.hostname !== "") {
|
||||
throw new TypeError(`Host must be empty.`);
|
||||
}
|
||||
|
||||
return decodeURIComponent(url.pathname);
|
||||
}
|
||||
|
||||
export function pathFromURL(pathOrUrl: string | URL): string {
|
||||
if (typeof pathOrUrl == "string") {
|
||||
try {
|
||||
pathOrUrl = new URL(pathOrUrl);
|
||||
} catch {}
|
||||
}
|
||||
if (pathOrUrl instanceof URL) {
|
||||
if (pathOrUrl.protocol != "file:") {
|
||||
throw new TypeError("Must be a path string or file URL.");
|
||||
}
|
||||
|
||||
return build.os == "windows"
|
||||
? pathFromURLWin32(pathOrUrl)
|
||||
: pathFromURLPosix(pathOrUrl);
|
||||
}
|
||||
return pathOrUrl;
|
||||
}
|
||||
|
||||
exposeForTest("pathFromURL", pathFromURL);
|
||||
|
|
|
@ -12,7 +12,7 @@ export interface WriteFileOptions {
|
|||
}
|
||||
|
||||
export function writeFileSync(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
data: Uint8Array,
|
||||
options: WriteFileOptions = {}
|
||||
): void {
|
||||
|
@ -42,7 +42,7 @@ export function writeFileSync(
|
|||
}
|
||||
|
||||
export async function writeFile(
|
||||
path: string,
|
||||
path: string | URL,
|
||||
data: Uint8Array,
|
||||
options: WriteFileOptions = {}
|
||||
): Promise<void> {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { open, openSync } from "./files.ts";
|
||||
import { writeAll, writeAllSync } from "./buffer.ts";
|
||||
|
||||
export function writeTextFileSync(path: string, data: string): void {
|
||||
export function writeTextFileSync(path: string | URL, data: string): void {
|
||||
const file = openSync(path, { write: true, create: true, truncate: true });
|
||||
const enc = new TextEncoder();
|
||||
const contents = enc.encode(data);
|
||||
|
@ -9,7 +9,10 @@ export function writeTextFileSync(path: string, data: string): void {
|
|||
file.close();
|
||||
}
|
||||
|
||||
export async function writeTextFile(path: string, data: string): Promise<void> {
|
||||
export async function writeTextFile(
|
||||
path: string | URL,
|
||||
data: string
|
||||
): Promise<void> {
|
||||
const file = await open(path, { write: true, create: true, truncate: true });
|
||||
const enc = new TextEncoder();
|
||||
const contents = enc.encode(data);
|
||||
|
|
|
@ -18,6 +18,25 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
|
||||
function chmodSyncUrl(): void {
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(`file://${tempDir}/test.txt`);
|
||||
Deno.writeFileSync(fileUrl, data, { mode: 0o666 });
|
||||
|
||||
Deno.chmodSync(fileUrl, 0o777);
|
||||
|
||||
const fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.mode);
|
||||
assertEquals(fileInfo.mode & 0o777, 0o777);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
// Check symlink when not on windows
|
||||
unitTest(
|
||||
{
|
||||
|
@ -89,6 +108,25 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
|
||||
async function chmodUrl(): Promise<void> {
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(`file://${tempDir}/test.txt`);
|
||||
Deno.writeFileSync(fileUrl, data, { mode: 0o666 });
|
||||
|
||||
await Deno.chmod(fileUrl, 0o777);
|
||||
|
||||
const fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.mode);
|
||||
assertEquals(fileInfo.mode & 0o777, 0o777);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
// Check symlink when not on windows
|
||||
|
||||
unitTest(
|
||||
|
|
|
@ -125,6 +125,26 @@ if (Deno.build.os !== "windows") {
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { run: true, write: true } },
|
||||
async function chownSyncWithUrl(): Promise<void> {
|
||||
// TODO: same as chownSyncSucceed
|
||||
const { uid, gid } = await getUidAndGid();
|
||||
|
||||
const enc = new TextEncoder();
|
||||
const dirPath = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(`file://${dirPath}/chown_test_file.txt`);
|
||||
const fileData = enc.encode("Hello");
|
||||
Deno.writeFileSync(fileUrl, fileData);
|
||||
|
||||
// the test script creates this file with the same uid and gid,
|
||||
// here chown is a noop so it succeeds under non-priviledged user
|
||||
Deno.chownSync(fileUrl, uid, gid);
|
||||
|
||||
Deno.removeSync(dirPath, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { run: true, write: true } },
|
||||
async function chownSucceed(): Promise<void> {
|
||||
|
@ -144,4 +164,24 @@ if (Deno.build.os !== "windows") {
|
|||
Deno.removeSync(dirPath, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { run: true, write: true } },
|
||||
async function chownWithUrl(): Promise<void> {
|
||||
// TODO: same as chownSyncSucceed
|
||||
const { uid, gid } = await getUidAndGid();
|
||||
|
||||
const enc = new TextEncoder();
|
||||
const dirPath = await Deno.makeTempDir();
|
||||
const fileUrl = new URL(`file://${dirPath}/chown_test_file.txt`);
|
||||
const fileData = enc.encode("Hello");
|
||||
await Deno.writeFile(fileUrl, fileData);
|
||||
|
||||
// the test script creates this file with the same uid and gid,
|
||||
// here chown is a noop so it succeeds under non-priviledged user
|
||||
await Deno.chown(fileUrl, uid, gid);
|
||||
|
||||
Deno.removeSync(dirPath, { recursive: true });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assert, assertEquals } from "./test_util.ts";
|
||||
|
||||
function readFileString(filename: string): string {
|
||||
function readFileString(filename: string | URL): string {
|
||||
const dataRead = Deno.readFileSync(filename);
|
||||
const dec = new TextDecoder("utf-8");
|
||||
return dec.decode(dataRead);
|
||||
}
|
||||
|
||||
function writeFileString(filename: string, s: string): void {
|
||||
function writeFileString(filename: string | URL, s: string): void {
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode(s);
|
||||
Deno.writeFileSync(filename, data, { mode: 0o666 });
|
||||
}
|
||||
|
||||
function assertSameContent(filename1: string, filename2: string): void {
|
||||
function assertSameContent(
|
||||
filename1: string | URL,
|
||||
filename2: string | URL
|
||||
): void {
|
||||
const data1 = Deno.readFileSync(filename1);
|
||||
const data2 = Deno.readFileSync(filename2);
|
||||
assertEquals(data1, data2);
|
||||
|
@ -31,6 +34,29 @@ unitTest(
|
|||
assertEquals(readFileString(fromFilename), "Hello world!");
|
||||
// Original == Dest
|
||||
assertSameContent(fromFilename, toFilename);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
function copyFileSyncByUrl(): void {
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fromUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/from.txt`
|
||||
);
|
||||
const toUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/to.txt`
|
||||
);
|
||||
writeFileString(fromUrl, "Hello world!");
|
||||
Deno.copyFileSync(fromUrl, toUrl);
|
||||
// No change to original file
|
||||
assertEquals(readFileString(fromUrl), "Hello world!");
|
||||
// Original == Dest
|
||||
assertSameContent(fromUrl, toUrl);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -49,6 +75,8 @@ unitTest(
|
|||
}
|
||||
assert(!!err);
|
||||
assert(err instanceof Deno.errors.NotFound);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -94,6 +122,8 @@ unitTest(
|
|||
assertEquals(readFileString(fromFilename), "Hello world!");
|
||||
// Original == Dest
|
||||
assertSameContent(fromFilename, toFilename);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -109,6 +139,29 @@ unitTest(
|
|||
assertEquals(readFileString(fromFilename), "Hello world!");
|
||||
// Original == Dest
|
||||
assertSameContent(fromFilename, toFilename);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function copyFileByUrl(): Promise<void> {
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fromUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/from.txt`
|
||||
);
|
||||
const toUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/to.txt`
|
||||
);
|
||||
writeFileString(fromUrl, "Hello world!");
|
||||
await Deno.copyFile(fromUrl, toUrl);
|
||||
// No change to original file
|
||||
assertEquals(readFileString(fromUrl), "Hello world!");
|
||||
// Original == Dest
|
||||
assertSameContent(fromUrl, toUrl);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -127,6 +180,8 @@ unitTest(
|
|||
}
|
||||
assert(!!err);
|
||||
assert(err instanceof Deno.errors.NotFound);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -144,6 +199,8 @@ unitTest(
|
|||
assertEquals(readFileString(fromFilename), "Hello world!");
|
||||
// Original == Dest
|
||||
assertSameContent(fromFilename, toFilename);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -197,6 +197,54 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{
|
||||
perms: { read: true, write: true },
|
||||
},
|
||||
function openSyncUrl(): void {
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test_open.txt`
|
||||
);
|
||||
const file = Deno.openSync(fileUrl, {
|
||||
write: true,
|
||||
createNew: true,
|
||||
mode: 0o626,
|
||||
});
|
||||
file.close();
|
||||
const pathInfo = Deno.statSync(fileUrl);
|
||||
if (Deno.build.os !== "windows") {
|
||||
assertEquals(pathInfo.mode! & 0o777, 0o626 & ~Deno.umask());
|
||||
}
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{
|
||||
perms: { read: true, write: true },
|
||||
},
|
||||
async function openUrl(): Promise<void> {
|
||||
const tempDir = await Deno.makeTempDir();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test_open.txt`
|
||||
);
|
||||
const file = await Deno.open(fileUrl, {
|
||||
write: true,
|
||||
createNew: true,
|
||||
mode: 0o626,
|
||||
});
|
||||
file.close();
|
||||
const pathInfo = Deno.statSync(fileUrl);
|
||||
if (Deno.build.os !== "windows") {
|
||||
assertEquals(pathInfo.mode! & 0o777, 0o626 & ~Deno.umask());
|
||||
}
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { write: false } },
|
||||
async function writePermFailure(): Promise<void> {
|
||||
|
@ -375,6 +423,71 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function createFileWithUrl(): Promise<void> {
|
||||
const tempDir = await Deno.makeTempDir();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
const f = await Deno.create(fileUrl);
|
||||
let fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.isFile);
|
||||
assert(fileInfo.size === 0);
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
await f.write(data);
|
||||
fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.size === 5);
|
||||
f.close();
|
||||
|
||||
await Deno.remove(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function createSyncFile(): Promise<void> {
|
||||
const tempDir = await Deno.makeTempDir();
|
||||
const filename = tempDir + "/test.txt";
|
||||
const f = Deno.createSync(filename);
|
||||
let fileInfo = Deno.statSync(filename);
|
||||
assert(fileInfo.isFile);
|
||||
assert(fileInfo.size === 0);
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
await f.write(data);
|
||||
fileInfo = Deno.statSync(filename);
|
||||
assert(fileInfo.size === 5);
|
||||
f.close();
|
||||
|
||||
// TODO: test different modes
|
||||
await Deno.remove(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function createSyncFileWithUrl(): Promise<void> {
|
||||
const tempDir = await Deno.makeTempDir();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
const f = Deno.createSync(fileUrl);
|
||||
let fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.isFile);
|
||||
assert(fileInfo.size === 0);
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
await f.write(data);
|
||||
fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.size === 5);
|
||||
f.close();
|
||||
|
||||
await Deno.remove(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function openModeWrite(): Promise<void> {
|
||||
|
|
31
cli/tests/unit/path_from_url_test.ts
Normal file
31
cli/tests/unit/path_from_url_test.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { assertThrows, assertEquals, unitTest } from "./test_util.ts";
|
||||
|
||||
// @ts-expect-error TypeScript (as of 3.7) does not support indexing namespaces by symbol
|
||||
const { pathFromURL } = Deno[Deno.internal];
|
||||
|
||||
unitTest(
|
||||
{ ignore: Deno.build.os === "windows" },
|
||||
function pathFromURLPosix(): void {
|
||||
assertEquals(pathFromURL("file:///test/directory"), "/test/directory");
|
||||
assertThrows(() => pathFromURL("file://host/test/directory"));
|
||||
assertThrows(() => pathFromURL("https://deno.land/welcome.ts"));
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ ignore: Deno.build.os !== "windows" },
|
||||
function pathFromURLWin32(): void {
|
||||
assertEquals(pathFromURL("file:///c:/windows/test"), "c:\\windows\\test");
|
||||
assertThrows(() => pathFromURL("file:///thing/test"));
|
||||
assertThrows(() => pathFromURL("https://deno.land/welcome.ts"));
|
||||
/* TODO(ry) Add tests for these situations
|
||||
* ampersand_&.tx file:///D:/weird_names/ampersand_&.txt
|
||||
* at_@.txt file:///D:/weird_names/at_@.txt
|
||||
* emoji_🙃.txt file:///D:/weird_names/emoji_%F0%9F%99%83.txt
|
||||
* percent_%.txt file:///D:/weird_names/percent_%25.txt
|
||||
* pound_#.txt file:///D:/weird_names/pound_%23.txt
|
||||
* space_ .txt file:///D:/weird_names/space_%20.txt
|
||||
* swapped_surrogate_pair_<EFBFBD><EFBFBD>.txt file:///D:/weird_names/swapped_surrogate_pair_%EF%BF%BD%EF%BF%BD.txt
|
||||
*/
|
||||
}
|
||||
);
|
|
@ -1,5 +1,10 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assert, assertEquals } from "./test_util.ts";
|
||||
import {
|
||||
unitTest,
|
||||
assert,
|
||||
assertEquals,
|
||||
pathToAbsoluteFileUrl,
|
||||
} from "./test_util.ts";
|
||||
|
||||
function assertSameContent(files: Deno.DirEntry[]): void {
|
||||
let counter = 0;
|
||||
|
@ -19,6 +24,11 @@ unitTest({ perms: { read: true } }, function readDirSyncSuccess(): void {
|
|||
assertSameContent(files);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, function readDirSyncWithUrl(): void {
|
||||
const files = [...Deno.readDirSync(pathToAbsoluteFileUrl("cli/tests"))];
|
||||
assertSameContent(files);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, function readDirSyncPerm(): void {
|
||||
let caughtError = false;
|
||||
try {
|
||||
|
@ -68,6 +78,18 @@ unitTest({ perms: { read: true } }, async function readDirSuccess(): Promise<
|
|||
assertSameContent(files);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, async function readDirWithUrl(): Promise<
|
||||
void
|
||||
> {
|
||||
const files = [];
|
||||
for await (const dirEntry of Deno.readDir(
|
||||
pathToAbsoluteFileUrl("cli/tests")
|
||||
)) {
|
||||
files.push(dirEntry);
|
||||
}
|
||||
assertSameContent(files);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, async function readDirPerm(): Promise<
|
||||
void
|
||||
> {
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assert, assertEquals } from "./test_util.ts";
|
||||
import {
|
||||
unitTest,
|
||||
assert,
|
||||
assertEquals,
|
||||
pathToAbsoluteFileUrl,
|
||||
} from "./test_util.ts";
|
||||
|
||||
unitTest({ perms: { read: true } }, function readFileSyncSuccess(): void {
|
||||
const data = Deno.readFileSync("cli/tests/fixture.json");
|
||||
|
@ -10,6 +15,17 @@ unitTest({ perms: { read: true } }, function readFileSyncSuccess(): void {
|
|||
assertEquals(pkg.name, "deno");
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, function readFileSyncUrl(): void {
|
||||
const data = Deno.readFileSync(
|
||||
pathToAbsoluteFileUrl("cli/tests/fixture.json")
|
||||
);
|
||||
assert(data.byteLength > 0);
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const json = decoder.decode(data);
|
||||
const pkg = JSON.parse(json);
|
||||
assertEquals(pkg.name, "deno");
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, function readFileSyncPerm(): void {
|
||||
let caughtError = false;
|
||||
try {
|
||||
|
@ -34,6 +50,19 @@ unitTest({ perms: { read: true } }, function readFileSyncNotFound(): void {
|
|||
assert(data === undefined);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, async function readFileUrl(): Promise<
|
||||
void
|
||||
> {
|
||||
const data = await Deno.readFile(
|
||||
pathToAbsoluteFileUrl("cli/tests/fixture.json")
|
||||
);
|
||||
assert(data.byteLength > 0);
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const json = decoder.decode(data);
|
||||
const pkg = JSON.parse(json);
|
||||
assertEquals(pkg.name, "deno");
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, async function readFileSuccess(): Promise<
|
||||
void
|
||||
> {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { unitTest, assert, assertEquals } from "./test_util.ts";
|
||||
import {
|
||||
unitTest,
|
||||
assert,
|
||||
assertEquals,
|
||||
pathToAbsoluteFileUrl,
|
||||
} from "./test_util.ts";
|
||||
|
||||
unitTest({ perms: { read: true } }, function readTextFileSyncSuccess(): void {
|
||||
const data = Deno.readTextFileSync("cli/tests/fixture.json");
|
||||
|
@ -7,6 +12,15 @@ unitTest({ perms: { read: true } }, function readTextFileSyncSuccess(): void {
|
|||
assertEquals(pkg.name, "deno");
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, function readTextFileSyncByUrl(): void {
|
||||
const data = Deno.readTextFileSync(
|
||||
pathToAbsoluteFileUrl("cli/tests/fixture.json")
|
||||
);
|
||||
assert(data.length > 0);
|
||||
const pkg = JSON.parse(data);
|
||||
assertEquals(pkg.name, "deno");
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, function readTextFileSyncPerm(): void {
|
||||
let caughtError = false;
|
||||
try {
|
||||
|
@ -41,6 +55,17 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest({ perms: { read: true } }, async function readTextFileByUrl(): Promise<
|
||||
void
|
||||
> {
|
||||
const data = await Deno.readTextFile(
|
||||
pathToAbsoluteFileUrl("cli/tests/fixture.json")
|
||||
);
|
||||
assert(data.length > 0);
|
||||
const pkg = JSON.parse(data);
|
||||
assertEquals(pkg.name, "deno");
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, async function readTextFilePerm(): Promise<
|
||||
void
|
||||
> {
|
||||
|
|
|
@ -51,6 +51,36 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { write: true, read: true } },
|
||||
async function removeFileByUrl(): Promise<void> {
|
||||
for (const method of REMOVE_METHODS) {
|
||||
// REMOVE FILE
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
|
||||
Deno.writeFileSync(fileUrl, data, { mode: 0o666 });
|
||||
const fileInfo = Deno.statSync(fileUrl);
|
||||
assert(fileInfo.isFile); // check exist first
|
||||
await Deno[method](fileUrl); // remove
|
||||
// We then check again after remove
|
||||
let err;
|
||||
try {
|
||||
Deno.statSync(fileUrl);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
// File is gone
|
||||
assert(err instanceof Deno.errors.NotFound);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { write: true, read: true } },
|
||||
async function removeFail(): Promise<void> {
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assert, assertEquals } from "./test_util.ts";
|
||||
import {
|
||||
unitTest,
|
||||
assert,
|
||||
assertEquals,
|
||||
pathToAbsoluteFileUrl,
|
||||
} from "./test_util.ts";
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
|
@ -18,12 +23,47 @@ unitTest(
|
|||
|
||||
const tempFile = Deno.makeTempFileSync();
|
||||
const tempInfo = Deno.statSync(tempFile);
|
||||
const now = Date.now();
|
||||
let now = Date.now();
|
||||
assert(tempInfo.atime !== null && now - tempInfo.atime.valueOf() < 1000);
|
||||
assert(tempInfo.mtime !== null && now - tempInfo.mtime.valueOf() < 1000);
|
||||
assert(
|
||||
tempInfo.birthtime === null || now - tempInfo.birthtime.valueOf() < 1000
|
||||
);
|
||||
|
||||
const packageInfoByUrl = Deno.statSync(pathToAbsoluteFileUrl("README.md"));
|
||||
assert(packageInfoByUrl.isFile);
|
||||
assert(!packageInfoByUrl.isSymlink);
|
||||
|
||||
const modulesInfoByUrl = Deno.statSync(
|
||||
pathToAbsoluteFileUrl("cli/tests/symlink_to_subdir")
|
||||
);
|
||||
assert(modulesInfoByUrl.isDirectory);
|
||||
assert(!modulesInfoByUrl.isSymlink);
|
||||
|
||||
const testsInfoByUrl = Deno.statSync(pathToAbsoluteFileUrl("cli/tests"));
|
||||
assert(testsInfoByUrl.isDirectory);
|
||||
assert(!testsInfoByUrl.isSymlink);
|
||||
|
||||
const tempFileForUrl = Deno.makeTempFileSync();
|
||||
const tempInfoByUrl = Deno.statSync(
|
||||
new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempFileForUrl}`
|
||||
)
|
||||
);
|
||||
now = Date.now();
|
||||
assert(
|
||||
tempInfoByUrl.atime !== null && now - tempInfoByUrl.atime.valueOf() < 1000
|
||||
);
|
||||
assert(
|
||||
tempInfoByUrl.mtime !== null && now - tempInfoByUrl.mtime.valueOf() < 1000
|
||||
);
|
||||
assert(
|
||||
tempInfoByUrl.birthtime === null ||
|
||||
now - tempInfoByUrl.birthtime.valueOf() < 1000
|
||||
);
|
||||
|
||||
Deno.removeSync(tempFile, { recursive: true });
|
||||
Deno.removeSync(tempFileForUrl, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -58,13 +98,27 @@ unitTest({ perms: { read: true } }, function lstatSyncSuccess(): void {
|
|||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
|
||||
const packageInfoByUrl = Deno.lstatSync(pathToAbsoluteFileUrl("README.md"));
|
||||
assert(packageInfoByUrl.isFile);
|
||||
assert(!packageInfoByUrl.isSymlink);
|
||||
|
||||
const modulesInfo = Deno.lstatSync("cli/tests/symlink_to_subdir");
|
||||
assert(!modulesInfo.isDirectory);
|
||||
assert(modulesInfo.isSymlink);
|
||||
|
||||
const modulesInfoByUrl = Deno.lstatSync(
|
||||
pathToAbsoluteFileUrl("cli/tests/symlink_to_subdir")
|
||||
);
|
||||
assert(!modulesInfoByUrl.isDirectory);
|
||||
assert(modulesInfoByUrl.isSymlink);
|
||||
|
||||
const coreInfo = Deno.lstatSync("core");
|
||||
assert(coreInfo.isDirectory);
|
||||
assert(!coreInfo.isSymlink);
|
||||
|
||||
const coreInfoByUrl = Deno.lstatSync(pathToAbsoluteFileUrl("core"));
|
||||
assert(coreInfoByUrl.isDirectory);
|
||||
assert(!coreInfoByUrl.isSymlink);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, function lstatSyncPerm(): void {
|
||||
|
@ -100,23 +154,60 @@ unitTest(
|
|||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
|
||||
const packageInfoByUrl = await Deno.stat(
|
||||
pathToAbsoluteFileUrl("README.md")
|
||||
);
|
||||
assert(packageInfoByUrl.isFile);
|
||||
assert(!packageInfoByUrl.isSymlink);
|
||||
|
||||
const modulesInfo = await Deno.stat("cli/tests/symlink_to_subdir");
|
||||
assert(modulesInfo.isDirectory);
|
||||
assert(!modulesInfo.isSymlink);
|
||||
|
||||
const modulesInfoByUrl = await Deno.stat(
|
||||
pathToAbsoluteFileUrl("cli/tests/symlink_to_subdir")
|
||||
);
|
||||
assert(modulesInfoByUrl.isDirectory);
|
||||
assert(!modulesInfoByUrl.isSymlink);
|
||||
|
||||
const testsInfo = await Deno.stat("cli/tests");
|
||||
assert(testsInfo.isDirectory);
|
||||
assert(!testsInfo.isSymlink);
|
||||
|
||||
const testsInfoByUrl = await Deno.stat(pathToAbsoluteFileUrl("cli/tests"));
|
||||
assert(testsInfoByUrl.isDirectory);
|
||||
assert(!testsInfoByUrl.isSymlink);
|
||||
|
||||
const tempFile = await Deno.makeTempFile();
|
||||
const tempInfo = await Deno.stat(tempFile);
|
||||
const now = Date.now();
|
||||
let now = Date.now();
|
||||
assert(tempInfo.atime !== null && now - tempInfo.atime.valueOf() < 1000);
|
||||
assert(tempInfo.mtime !== null && now - tempInfo.mtime.valueOf() < 1000);
|
||||
|
||||
assert(
|
||||
tempInfo.birthtime === null || now - tempInfo.birthtime.valueOf() < 1000
|
||||
);
|
||||
|
||||
const tempFileForUrl = await Deno.makeTempFile();
|
||||
const tempInfoByUrl = await Deno.stat(
|
||||
new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempFileForUrl}`
|
||||
)
|
||||
);
|
||||
now = Date.now();
|
||||
assert(
|
||||
tempInfoByUrl.atime !== null && now - tempInfoByUrl.atime.valueOf() < 1000
|
||||
);
|
||||
assert(
|
||||
tempInfoByUrl.mtime !== null && now - tempInfoByUrl.mtime.valueOf() < 1000
|
||||
);
|
||||
assert(
|
||||
tempInfoByUrl.birthtime === null ||
|
||||
now - tempInfoByUrl.birthtime.valueOf() < 1000
|
||||
);
|
||||
|
||||
Deno.removeSync(tempFile, { recursive: true });
|
||||
Deno.removeSync(tempFileForUrl, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -155,13 +246,27 @@ unitTest({ perms: { read: true } }, async function lstatSuccess(): Promise<
|
|||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
|
||||
const packageInfoByUrl = await Deno.lstat(pathToAbsoluteFileUrl("README.md"));
|
||||
assert(packageInfoByUrl.isFile);
|
||||
assert(!packageInfoByUrl.isSymlink);
|
||||
|
||||
const modulesInfo = await Deno.lstat("cli/tests/symlink_to_subdir");
|
||||
assert(!modulesInfo.isDirectory);
|
||||
assert(modulesInfo.isSymlink);
|
||||
|
||||
const modulesInfoByUrl = await Deno.lstat(
|
||||
pathToAbsoluteFileUrl("cli/tests/symlink_to_subdir")
|
||||
);
|
||||
assert(!modulesInfoByUrl.isDirectory);
|
||||
assert(modulesInfoByUrl.isSymlink);
|
||||
|
||||
const coreInfo = await Deno.lstat("core");
|
||||
assert(coreInfo.isDirectory);
|
||||
assert(!coreInfo.isSymlink);
|
||||
|
||||
const coreInfoByUrl = await Deno.lstat(pathToAbsoluteFileUrl("core"));
|
||||
assert(coreInfoByUrl.isDirectory);
|
||||
assert(!coreInfoByUrl.isSymlink);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: false } }, async function lstatPerm(): Promise<void> {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { assert, assertEquals } from "../../../std/testing/asserts.ts";
|
||||
import { resolve } from "../../../std/path/mod.ts";
|
||||
export {
|
||||
assert,
|
||||
assertThrows,
|
||||
|
@ -363,3 +364,9 @@ unitTest(
|
|||
});
|
||||
}
|
||||
);
|
||||
|
||||
export function pathToAbsoluteFileUrl(path: string): URL {
|
||||
path = resolve(path);
|
||||
|
||||
return new URL(`file://${Deno.build.os === "windows" ? "/" : ""}${path}`);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import "./mkdir_test.ts";
|
|||
import "./net_test.ts";
|
||||
import "./os_test.ts";
|
||||
import "./permissions_test.ts";
|
||||
import "./path_from_url_test.ts";
|
||||
import "./process_test.ts";
|
||||
import "./real_path_test.ts";
|
||||
import "./read_dir_test.ts";
|
||||
|
|
|
@ -15,6 +15,25 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
function writeFileSyncUrl(): void {
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
Deno.writeFileSync(fileUrl, data);
|
||||
const dataRead = Deno.readFileSync(fileUrl);
|
||||
const dec = new TextDecoder("utf-8");
|
||||
const actual = dec.decode(dataRead);
|
||||
assertEquals("Hello", actual);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest({ perms: { write: true } }, function writeFileSyncFail(): void {
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
|
@ -125,6 +144,25 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function writeFileUrl(): Promise<void> {
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const tempDir = await Deno.makeTempDir();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
await Deno.writeFile(fileUrl, data);
|
||||
const dataRead = Deno.readFileSync(fileUrl);
|
||||
const dec = new TextDecoder("utf-8");
|
||||
const actual = dec.decode(dataRead);
|
||||
assertEquals("Hello", actual);
|
||||
|
||||
Deno.removeSync(tempDir, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function writeFileNotFound(): Promise<void> {
|
||||
|
|
|
@ -10,6 +10,21 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
function writeTextFileSyncByUrl(): void {
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
Deno.writeTextFileSync(fileUrl, "Hello");
|
||||
const dataRead = Deno.readTextFileSync(fileUrl);
|
||||
assertEquals("Hello", dataRead);
|
||||
|
||||
Deno.removeSync(fileUrl, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest({ perms: { write: true } }, function writeTextFileSyncFail(): void {
|
||||
const filename = "/baddir/test.txt";
|
||||
// The following should fail because /baddir doesn't exist (hopefully).
|
||||
|
@ -46,6 +61,21 @@ unitTest(
|
|||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function writeTextFileByUrl(): Promise<void> {
|
||||
const tempDir = Deno.makeTempDirSync();
|
||||
const fileUrl = new URL(
|
||||
`file://${Deno.build.os === "windows" ? "/" : ""}${tempDir}/test.txt`
|
||||
);
|
||||
await Deno.writeTextFile(fileUrl, "Hello");
|
||||
const dataRead = Deno.readTextFileSync(fileUrl);
|
||||
assertEquals("Hello", dataRead);
|
||||
|
||||
Deno.removeSync(fileUrl, { recursive: true });
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function writeTextFileNotFound(): Promise<void> {
|
||||
|
|
Loading…
Reference in a new issue