diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/deno.ts | 4 | ||||
-rw-r--r-- | js/os.ts | 109 | ||||
-rw-r--r-- | js/os_test.ts | 62 | ||||
-rw-r--r-- | js/stat.ts | 143 | ||||
-rw-r--r-- | js/stat_test.ts | 126 | ||||
-rw-r--r-- | js/unit_tests.ts | 1 |
6 files changed, 271 insertions, 174 deletions
diff --git a/js/deno.ts b/js/deno.ts index 8908d7b67..a1eb639bb 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -4,14 +4,12 @@ export { env, exit, - FileInfo, makeTempDirSync, renameSync, - statSync, - lstatSync } from "./os"; export { mkdirSync, mkdir } from "./mkdir"; export { readFileSync, readFile } from "./read_file"; +export { FileInfo, statSync, lstatSync, stat, lstat } from "./stat"; export { writeFileSync, writeFile } from "./write_file"; export { ErrorKind, DenoError } from "./errors"; export { libdeno } from "./libdeno"; @@ -166,115 +166,6 @@ export function env(): { [index: string]: string } { } /** - * A FileInfo describes a file and is returned by `stat`, `lstat`, - * `statSync`, `lstatSync`. - */ -export class FileInfo { - private readonly _isFile: boolean; - private readonly _isSymlink: boolean; - /** The size of the file, in bytes. */ - len: number; - /** - * The last modification time of the file. This corresponds to the `mtime` - * field from `stat` on Unix and `ftLastWriteTime` on Windows. This may not - * be available on all platforms. - */ - modified: number | null; - /** - * The last access time of the file. This corresponds to the `atime` - * field from `stat` on Unix and `ftLastAccessTime` on Windows. This may not - * be available on all platforms. - */ - accessed: number | null; - /** - * The last access time of the file. This corresponds to the `birthtime` - * field from `stat` on Unix and `ftCreationTime` on Windows. This may not - * be available on all platforms. - */ - created: number | null; - - /* @internal */ - constructor(private _msg: fbs.StatSyncRes) { - const modified = this._msg.modified().toFloat64(); - const accessed = this._msg.accessed().toFloat64(); - const created = this._msg.created().toFloat64(); - - this._isFile = this._msg.isFile(); - this._isSymlink = this._msg.isSymlink(); - this.len = this._msg.len().toFloat64(); - this.modified = modified ? modified : null; - this.accessed = accessed ? accessed : null; - this.created = created ? created : null; - } - - /** - * Returns whether this is info for a regular file. This result is mutually - * exclusive to `FileInfo.isDirectory` and `FileInfo.isSymlink`. - */ - isFile() { - return this._isFile; - } - - /** - * Returns whether this is info for a regular directory. This result is - * mutually exclusive to `FileInfo.isFile` and `FileInfo.isSymlink`. - */ - isDirectory() { - return !this._isFile && !this._isSymlink; - } - - /** - * Returns whether this is info for a symlink. This result is - * mutually exclusive to `FileInfo.isFile` and `FileInfo.isDirectory`. - */ - isSymlink() { - return this._isSymlink; - } -} - -/** - * Queries the file system for information on the path provided. - * If the given path is a symlink information about the symlink will - * be returned. - * @returns FileInfo - */ -export function lstatSync(filename: string): FileInfo { - return statSyncInner(filename, true); -} - -/** - * Queries the file system for information on the path provided. - * `statSync` Will always follow symlinks. - * @returns FileInfo - */ -export function statSync(filename: string): FileInfo { - return statSyncInner(filename, false); -} - -function statSyncInner(filename: string, lstat: boolean): FileInfo { - /* Ideally we could write - const res = sendSync({ - command: fbs.Command.STAT_FILE_SYNC, - StatFilename: filename, - StatLStat: lstat, - }); - return new FileInfo(res); - */ - const builder = new flatbuffers.Builder(); - const filename_ = builder.createString(filename); - fbs.StatSync.startStatSync(builder); - fbs.StatSync.addFilename(builder, filename_); - fbs.StatSync.addLstat(builder, lstat); - const msg = fbs.StatSync.endStatSync(builder); - const baseRes = sendSync(builder, fbs.Any.StatSync, msg); - assert(baseRes != null); - assert(fbs.Any.StatSyncRes === baseRes!.msgType()); - const res = new fbs.StatSyncRes(); - assert(baseRes!.msg(res) != null); - return new FileInfo(res); -} - -/** * Renames (moves) oldpath to newpath. * import { renameSync } from "deno"; * const oldpath = 'from/path'; diff --git a/js/os_test.ts b/js/os_test.ts index 4c5da1505..c0198095c 100644 --- a/js/os_test.ts +++ b/js/os_test.ts @@ -23,68 +23,6 @@ test(async function envFailure() { assert(caughtError); }); -// TODO Add tests for modified, accessed, and created fields once there is a way -// to create temp files. -test(async function statSyncSuccess() { - const packageInfo = deno.statSync("package.json"); - assert(packageInfo.isFile()); - assert(!packageInfo.isSymlink()); - - const testingInfo = deno.statSync("testing"); - assert(testingInfo.isDirectory()); - assert(!testingInfo.isSymlink()); - - const srcInfo = deno.statSync("src"); - assert(srcInfo.isDirectory()); - assert(!srcInfo.isSymlink()); -}); - -test(async function statSyncNotFound() { - let caughtError = false; - let badInfo; - - try { - badInfo = deno.statSync("bad_file_name"); - } catch (err) { - caughtError = true; - assertEqual(err.kind, deno.ErrorKind.NotFound); - assertEqual(err.name, "NotFound"); - } - - assert(caughtError); - assertEqual(badInfo, undefined); -}); - -test(async function lstatSyncSuccess() { - const packageInfo = deno.lstatSync("package.json"); - assert(packageInfo.isFile()); - assert(!packageInfo.isSymlink()); - - const testingInfo = deno.lstatSync("testing"); - assert(!testingInfo.isDirectory()); - assert(testingInfo.isSymlink()); - - const srcInfo = deno.lstatSync("src"); - assert(srcInfo.isDirectory()); - assert(!srcInfo.isSymlink()); -}); - -test(async function lstatSyncNotFound() { - let caughtError = false; - let badInfo; - - try { - badInfo = deno.lstatSync("bad_file_name"); - } catch (err) { - caughtError = true; - assertEqual(err.kind, deno.ErrorKind.NotFound); - assertEqual(err.name, "NotFound"); - } - - assert(caughtError); - assertEqual(badInfo, undefined); -}); - testPerm({ write: true }, function makeTempDirSync() { const dir1 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); const dir2 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); diff --git a/js/stat.ts b/js/stat.ts new file mode 100644 index 000000000..49902b396 --- /dev/null +++ b/js/stat.ts @@ -0,0 +1,143 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. +import * as fbs from "gen/msg_generated"; +import { flatbuffers } from "flatbuffers"; +import * as dispatch from "./dispatch"; +import { assert } from "./util"; + +/** + * A FileInfo describes a file and is returned by `stat`, `lstat`, + * `statSync`, `lstatSync`. + */ +export class FileInfo { + private readonly _isFile: boolean; + private readonly _isSymlink: boolean; + /** The size of the file, in bytes. */ + len: number; + /** + * The last modification time of the file. This corresponds to the `mtime` + * field from `stat` on Unix and `ftLastWriteTime` on Windows. This may not + * be available on all platforms. + */ + modified: number | null; + /** + * The last access time of the file. This corresponds to the `atime` + * field from `stat` on Unix and `ftLastAccessTime` on Windows. This may not + * be available on all platforms. + */ + accessed: number | null; + /** + * The last access time of the file. This corresponds to the `birthtime` + * field from `stat` on Unix and `ftCreationTime` on Windows. This may not + * be available on all platforms. + */ + created: number | null; + + /* @internal */ + constructor(private _msg: fbs.StatRes) { + const modified = this._msg.modified().toFloat64(); + const accessed = this._msg.accessed().toFloat64(); + const created = this._msg.created().toFloat64(); + + this._isFile = this._msg.isFile(); + this._isSymlink = this._msg.isSymlink(); + this.len = this._msg.len().toFloat64(); + this.modified = modified ? modified : null; + this.accessed = accessed ? accessed : null; + this.created = created ? created : null; + } + + /** + * Returns whether this is info for a regular file. This result is mutually + * exclusive to `FileInfo.isDirectory` and `FileInfo.isSymlink`. + */ + isFile() { + return this._isFile; + } + + /** + * Returns whether this is info for a regular directory. This result is + * mutually exclusive to `FileInfo.isFile` and `FileInfo.isSymlink`. + */ + isDirectory() { + return !this._isFile && !this._isSymlink; + } + + /** + * Returns whether this is info for a symlink. This result is + * mutually exclusive to `FileInfo.isFile` and `FileInfo.isDirectory`. + */ + isSymlink() { + return this._isSymlink; + } +} + +/** + * Queries the file system for information on the path provided. + * If the given path is a symlink information about the symlink will + * be returned. + * + * import { lstat } from "deno"; + * const fileInfo = await deno.lstat("hello.txt"); + * assert(fileInfo.isFile()); + */ +export async function lstat(filename: string): Promise<FileInfo> { + return res(await dispatch.sendAsync(...req(filename, true))); +} + +/** + * Queries the file system for information on the path provided synchronously. + * If the given path is a symlink information about the symlink will + * be returned. + * + * import { lstatSync } from "deno"; + * const fileInfo = deno.lstatSync("hello.txt"); + * assert(fileInfo.isFile()); + */ +export function lstatSync(filename: string): FileInfo { + return res(dispatch.sendSync(...req(filename, true))); +} + +/** + * Queries the file system for information on the path provided. + * `stat` Will always follow symlinks. + * + * import { stat } from "deno"; + * const fileInfo = await deno.stat("hello.txt"); + * assert(fileInfo.isFile()); + */ +export async function stat(filename: string): Promise<FileInfo> { + return res(await dispatch.sendAsync(...req(filename, false))); +} + +/** + * Queries the file system for information on the path provided synchronously. + * `statSync` Will always follow symlinks. + * + * import { statSync } from "deno"; + * const fileInfo = deno.statSync("hello.txt"); + * assert(fileInfo.isFile()); + */ +export function statSync(filename: string): FileInfo { + return res(dispatch.sendSync(...req(filename, false))); +} + +function req( + filename: string, + lstat: boolean +): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] { + const builder = new flatbuffers.Builder(); + const filename_ = builder.createString(filename); + fbs.Stat.startStat(builder); + fbs.Stat.addFilename(builder, filename_); + fbs.Stat.addLstat(builder, lstat); + const msg = fbs.Stat.endStat(builder); + return [builder, fbs.Any.Stat, msg]; +} + +function res(baseRes: null | fbs.Base): FileInfo { + assert(baseRes != null); + assert(fbs.Any.StatRes === baseRes!.msgType()); + const res = new fbs.StatRes(); + assert(baseRes!.msg(res) != null); + return new FileInfo(res); +} diff --git a/js/stat_test.ts b/js/stat_test.ts new file mode 100644 index 000000000..c811b23ab --- /dev/null +++ b/js/stat_test.ts @@ -0,0 +1,126 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. +import { test, assert, assertEqual } from "./test_util.ts"; +import * as deno from "deno"; + +// TODO Add tests for modified, accessed, and created fields once there is a way +// to create temp files. +test(async function statSyncSuccess() { + const packageInfo = deno.statSync("package.json"); + assert(packageInfo.isFile()); + assert(!packageInfo.isSymlink()); + + const testingInfo = deno.statSync("testing"); + assert(testingInfo.isDirectory()); + assert(!testingInfo.isSymlink()); + + const srcInfo = deno.statSync("src"); + assert(srcInfo.isDirectory()); + assert(!srcInfo.isSymlink()); +}); + +test(async function statSyncNotFound() { + let caughtError = false; + let badInfo; + + try { + badInfo = deno.statSync("bad_file_name"); + } catch (err) { + caughtError = true; + assertEqual(err.kind, deno.ErrorKind.NotFound); + assertEqual(err.name, "NotFound"); + } + + assert(caughtError); + assertEqual(badInfo, undefined); +}); + +test(async function lstatSyncSuccess() { + const packageInfo = deno.lstatSync("package.json"); + assert(packageInfo.isFile()); + assert(!packageInfo.isSymlink()); + + const testingInfo = deno.lstatSync("testing"); + assert(!testingInfo.isDirectory()); + assert(testingInfo.isSymlink()); + + const srcInfo = deno.lstatSync("src"); + assert(srcInfo.isDirectory()); + assert(!srcInfo.isSymlink()); +}); + +test(async function lstatSyncNotFound() { + let caughtError = false; + let badInfo; + + try { + badInfo = deno.lstatSync("bad_file_name"); + } catch (err) { + caughtError = true; + assertEqual(err.kind, deno.ErrorKind.NotFound); + assertEqual(err.name, "NotFound"); + } + + assert(caughtError); + assertEqual(badInfo, undefined); +}); + +test(async function statSuccess() { + const packageInfo = await deno.stat("package.json"); + assert(packageInfo.isFile()); + assert(!packageInfo.isSymlink()); + + const testingInfo = await deno.stat("testing"); + assert(testingInfo.isDirectory()); + assert(!testingInfo.isSymlink()); + + const srcInfo = await deno.stat("src"); + assert(srcInfo.isDirectory()); + assert(!srcInfo.isSymlink()); +}); + +test(async function statNotFound() { + let caughtError = false; + let badInfo; + + try { + badInfo = await deno.stat("bad_file_name"); + } catch (err) { + caughtError = true; + assertEqual(err.kind, deno.ErrorKind.NotFound); + assertEqual(err.name, "NotFound"); + } + + assert(caughtError); + assertEqual(badInfo, undefined); +}); + +test(async function lstatSuccess() { + const packageInfo = await deno.lstat("package.json"); + assert(packageInfo.isFile()); + assert(!packageInfo.isSymlink()); + + const testingInfo = await deno.lstat("testing"); + assert(!testingInfo.isDirectory()); + assert(testingInfo.isSymlink()); + + const srcInfo = await deno.lstat("src"); + assert(srcInfo.isDirectory()); + assert(!srcInfo.isSymlink()); +}); + +test(async function lstatNotFound() { + let caughtError = false; + let badInfo; + + try { + badInfo = await deno.lstat("bad_file_name"); + } catch (err) { + caughtError = true; + assertEqual(err.kind, deno.ErrorKind.NotFound); + assertEqual(err.name, "NotFound"); + } + + assert(caughtError); + assertEqual(badInfo, undefined); +}); + diff --git a/js/unit_tests.ts b/js/unit_tests.ts index e00cfc116..88e6fb9d9 100644 --- a/js/unit_tests.ts +++ b/js/unit_tests.ts @@ -8,3 +8,4 @@ import "./os_test.ts"; import "./read_file_test.ts"; import "./write_file_test.ts"; import "./mkdir_test.ts"; +import "./stat_test.ts"; |