diff --git a/BUILD.gn b/BUILD.gn index 167ae82fbd..c48afcf83f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -66,6 +66,7 @@ ts_sources = [ "js/libdeno.ts", "js/main.ts", "js/mkdir.ts", + "js/make_temp_dir.ts", "js/mock_builtin.js", "js/os.ts", "js/plugins.d.ts", diff --git a/js/deno.ts b/js/deno.ts index 187d0f27f7..7ff763e8d7 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -1,8 +1,9 @@ // Copyright 2018 the Deno authors. All rights reserved. MIT license. // Public deno module. /// -export { env, exit, makeTempDirSync } from "./os"; +export { env, exit } from "./os"; export { mkdirSync, mkdir } from "./mkdir"; +export { makeTempDirSync, makeTempDir } from "./make_temp_dir"; export { removeSync, remove, removeAllSync, removeAll } from "./remove"; export { readFileSync, readFile } from "./read_file"; export { renameSync, rename } from "./rename"; diff --git a/js/make_temp_dir.ts b/js/make_temp_dir.ts new file mode 100644 index 0000000000..b252be3810 --- /dev/null +++ b/js/make_temp_dir.ts @@ -0,0 +1,74 @@ +// 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"; + +export interface MakeTempDirOptions { + dir?: string; + prefix?: string; + suffix?: string; +} + +/** + * makeTempDirSync is the synchronous version of `makeTempDir`. + * + * import { makeTempDirSync } from "deno"; + * const tempDirName0 = makeTempDirSync(); + * const tempDirName1 = makeTempDirSync({ prefix: 'my_temp' }); + */ +export function makeTempDirSync(options: MakeTempDirOptions = {}): string { + return res(dispatch.sendSync(...req(options))); +} + +/** + * makeTempDir creates a new temporary directory in the directory `dir`, its + * name beginning with `prefix` and ending with `suffix`. + * It returns the full path to the newly created directory. + * If `dir` is unspecified, tempDir uses the default directory for temporary + * files. Multiple programs calling tempDir simultaneously will not choose the + * same directory. It is the caller's responsibility to remove the directory + * when no longer needed. + * + * import { makeTempDir } from "deno"; + * const tempDirName0 = await makeTempDir(); + * const tempDirName1 = await makeTempDir({ prefix: 'my_temp' }); + */ +export async function makeTempDir( + options: MakeTempDirOptions = {} +): Promise { + return res(await dispatch.sendAsync(...req(options))); +} + +function req({ + dir, + prefix, + suffix +}: MakeTempDirOptions): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] { + const builder = new flatbuffers.Builder(); + const fbDir = dir == null ? -1 : builder.createString(dir); + const fbPrefix = prefix == null ? -1 : builder.createString(prefix); + const fbSuffix = suffix == null ? -1 : builder.createString(suffix); + fbs.MakeTempDir.startMakeTempDir(builder); + if (dir != null) { + fbs.MakeTempDir.addDir(builder, fbDir); + } + if (prefix != null) { + fbs.MakeTempDir.addPrefix(builder, fbPrefix); + } + if (suffix != null) { + fbs.MakeTempDir.addSuffix(builder, fbSuffix); + } + const msg = fbs.MakeTempDir.endMakeTempDir(builder); + return [builder, fbs.Any.MakeTempDir, msg]; +} + +function res(baseRes: null | fbs.Base): string { + assert(baseRes != null); + assert(fbs.Any.MakeTempDirRes === baseRes!.msgType()); + const res = new fbs.MakeTempDirRes(); + assert(baseRes!.msg(res) != null); + const path = res.path(); + assert(path != null); + return path!; +} diff --git a/js/make_temp_dir_test.ts b/js/make_temp_dir_test.ts new file mode 100644 index 0000000000..082c1e65d2 --- /dev/null +++ b/js/make_temp_dir_test.ts @@ -0,0 +1,67 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. +import { test, testPerm, assert, assertEqual } from "./test_util.ts"; +import * as deno from "deno"; + +testPerm({ write: true }, function makeTempDirSyncSuccess() { + const dir1 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); + const dir2 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); + // Check that both dirs are different. + assert(dir1 != dir2); + for (const dir of [dir1, dir2]) { + // Check that the prefix and suffix are applied. + const lastPart = dir.replace(/^.*[\\\/]/, ""); + assert(lastPart.startsWith("hello")); + assert(lastPart.endsWith("world")); + } + // Check that the `dir` option works. + const dir3 = deno.makeTempDirSync({ dir: dir1 }); + assert(dir3.startsWith(dir1)); + assert(/^[\\\/]/.test(dir3.slice(dir1.length))); + // Check that creating a temp dir inside a nonexisting directory fails. + let err; + try { + deno.makeTempDirSync({ dir: "/baddir" }); + } catch (err_) { + err = err_; + } + assertEqual(err.kind, deno.ErrorKind.NotFound); + assertEqual(err.name, "NotFound"); +}); + +test(function makeTempDirSyncPerm() { + // makeTempDirSync should require write permissions (for now). + let err; + try { + deno.makeTempDirSync({ dir: "/baddir" }); + } catch (err_) { + err = err_; + } + assertEqual(err.kind, deno.ErrorKind.PermissionDenied); + assertEqual(err.name, "PermissionDenied"); +}); + +testPerm({ write: true }, async function makeTempDirSuccess() { + const dir1 = await deno.makeTempDir({ prefix: "hello", suffix: "world" }); + const dir2 = await deno.makeTempDir({ prefix: "hello", suffix: "world" }); + // Check that both dirs are different. + assert(dir1 != dir2); + for (const dir of [dir1, dir2]) { + // Check that the prefix and suffix are applied. + const lastPart = dir.replace(/^.*[\\\/]/, ""); + assert(lastPart.startsWith("hello")); + assert(lastPart.endsWith("world")); + } + // Check that the `dir` option works. + const dir3 = await deno.makeTempDir({ dir: dir1 }); + assert(dir3.startsWith(dir1)); + assert(/^[\\\/]/.test(dir3.slice(dir1.length))); + // Check that creating a temp dir inside a nonexisting directory fails. + let err; + try { + await deno.makeTempDir({ dir: "/baddir" }); + } catch (err_) { + err = err_; + } + assertEqual(err.kind, deno.ErrorKind.NotFound); + assertEqual(err.name, "NotFound"); +}); diff --git a/js/os.ts b/js/os.ts index d73865c065..020d834c6b 100644 --- a/js/os.ts +++ b/js/os.ts @@ -63,50 +63,6 @@ export function codeCache( assert(baseRes == null); // Expect null or error. } -/** - * makeTempDirSync creates a new temporary directory in the directory `dir`, its - * name beginning with `prefix` and ending with `suffix`. - * It returns the full path to the newly created directory. - * If `dir` is unspecified, tempDir uses the default directory for temporary - * files. Multiple programs calling tempDir simultaneously will not choose the - * same directory. It is the caller's responsibility to remove the directory - * when no longer needed. - */ -export interface MakeTempDirOptions { - dir?: string; - prefix?: string; - suffix?: string; -} -export function makeTempDirSync({ - dir, - prefix, - suffix -}: MakeTempDirOptions = {}): string { - const builder = new flatbuffers.Builder(); - const fbDir = dir == null ? -1 : builder.createString(dir); - const fbPrefix = prefix == null ? -1 : builder.createString(prefix); - const fbSuffix = suffix == null ? -1 : builder.createString(suffix); - fbs.MakeTempDir.startMakeTempDir(builder); - if (dir != null) { - fbs.MakeTempDir.addDir(builder, fbDir); - } - if (prefix != null) { - fbs.MakeTempDir.addPrefix(builder, fbPrefix); - } - if (suffix != null) { - fbs.MakeTempDir.addSuffix(builder, fbSuffix); - } - const msg = fbs.MakeTempDir.endMakeTempDir(builder); - const baseRes = sendSync(builder, fbs.Any.MakeTempDir, msg); - assert(baseRes != null); - assert(fbs.Any.MakeTempDirRes === baseRes!.msgType()); - const res = new fbs.MakeTempDirRes(); - assert(baseRes!.msg(res) != null); - const path = res.path(); - assert(path != null); - return path!; -} - function createEnv(_msg: fbs.EnvironRes): { [index: string]: string } { const env: { [index: string]: string } = {}; diff --git a/js/os_test.ts b/js/os_test.ts index 61227a3b10..922d86850e 100644 --- a/js/os_test.ts +++ b/js/os_test.ts @@ -22,41 +22,3 @@ test(async function envFailure() { assert(caughtError); }); - -testPerm({ write: true }, function makeTempDirSync() { - const dir1 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); - const dir2 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); - // Check that both dirs are different. - assert(dir1 != dir2); - for (const dir of [dir1, dir2]) { - // Check that the prefix and suffix are applied. - const lastPart = dir.replace(/^.*[\\\/]/, ""); - assert(lastPart.startsWith("hello")); - assert(lastPart.endsWith("world")); - } - // Check that the `dir` option works. - const dir3 = deno.makeTempDirSync({ dir: dir1 }); - assert(dir3.startsWith(dir1)); - assert(/^[\\\/]/.test(dir3.slice(dir1.length))); - // Check that creating a temp dir inside a nonexisting directory fails. - let err; - try { - deno.makeTempDirSync({ dir: "/baddir" }); - } catch (err_) { - err = err_; - } - assertEqual(err.kind, deno.ErrorKind.NotFound); - assertEqual(err.name, "NotFound"); -}); - -test(function makeTempDirSyncPerm() { - // makeTempDirSync should require write permissions (for now). - let err; - try { - deno.makeTempDirSync({ dir: "/baddir" }); - } catch (err_) { - err = err_; - } - assertEqual(err.kind, deno.ErrorKind.PermissionDenied); - assertEqual(err.name, "PermissionDenied"); -}); diff --git a/js/unit_tests.ts b/js/unit_tests.ts index b406b63d08..be947cd675 100644 --- a/js/unit_tests.ts +++ b/js/unit_tests.ts @@ -8,5 +8,6 @@ import "./os_test.ts"; import "./read_file_test.ts"; import "./write_file_test.ts"; import "./mkdir_test.ts"; +import "./make_temp_dir_test.ts"; import "./stat_test.ts"; import "./rename_test.ts";