diff --git a/BUILD.gn b/BUILD.gn index 5532850c0f..42859a3715 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -195,6 +195,7 @@ run_node("gen_declarations") { "js/fetch.ts", "js/global-eval.ts", "js/globals.ts", + "js/mkdir.ts", "js/os.ts", "js/read_file.ts", "js/text_encoding.ts", @@ -233,6 +234,7 @@ run_node("bundle") { "js/fetch_types.d.ts", "js/globals.ts", "js/main.ts", + "js/mkdir.ts", "js/os.ts", "js/plugins.d.ts", "js/read_file.ts", diff --git a/js/deno.ts b/js/deno.ts index ce01c5dad6..fab8ef4e29 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -6,12 +6,12 @@ export { exit, FileInfo, makeTempDirSync, - mkdirSync, renameSync, statSync, lstatSync, writeFileSync } from "./os"; +export { mkdirSync, mkdir } from "./mkdir"; export { readFileSync, readFile } from "./read_file"; export { ErrorKind, DenoError } from "./errors"; export { libdeno } from "./libdeno"; diff --git a/js/mkdir.ts b/js/mkdir.ts new file mode 100644 index 0000000000..8e76fc17ea --- /dev/null +++ b/js/mkdir.ts @@ -0,0 +1,37 @@ +// 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"; + +/** + * Creates a new directory with the specified path and permission synchronously. + * + * import { mkdirSync } from "deno"; + * mkdirSync("new_dir"); + */ +export function mkdirSync(path: string, mode = 0o777): void { + dispatch.sendSync(...req(path, mode)); +} + +/** + * Creates a new directory with the specified path and permission. + * + * import { mkdir } from "deno"; + * await mkdir("new_dir"); + */ +export async function mkdir(path: string, mode = 0o777): Promise { + await dispatch.sendAsync(...req(path, mode)); +} + +function req( + path: string, + mode: number +): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] { + const builder = new flatbuffers.Builder(); + const path_ = builder.createString(path); + fbs.Mkdir.startMkdir(builder); + fbs.Mkdir.addPath(builder, path_); + fbs.Mkdir.addMode(builder, mode); + const msg = fbs.Mkdir.endMkdir(builder); + return [builder, fbs.Any.Mkdir, msg]; +} diff --git a/js/mkdir_test.ts b/js/mkdir_test.ts new file mode 100644 index 0000000000..ed275bd363 --- /dev/null +++ b/js/mkdir_test.ts @@ -0,0 +1,28 @@ +// 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 mkdirSyncSuccess() { + const path = deno.makeTempDirSync() + "/dir/subdir"; + deno.mkdirSync(path); + const pathInfo = deno.statSync(path); + assert(pathInfo.isDirectory()); +}); + +testPerm({ write: false }, function mkdirSyncPerm() { + let err; + try { + deno.mkdirSync("/baddir"); + } catch (e) { + err = e; + } + assertEqual(err.kind, deno.ErrorKind.PermissionDenied); + assertEqual(err.name, "PermissionDenied"); +}); + +testPerm({ write: true }, async function mkdirSuccess() { + const path = deno.makeTempDirSync() + "/dir/subdir"; + await deno.mkdir(path); + const pathInfo = deno.statSync(path); + assert(pathInfo.isDirectory()); +}); diff --git a/js/os.ts b/js/os.ts index d29d0d74a5..4849ac19fd 100644 --- a/js/os.ts +++ b/js/os.ts @@ -107,25 +107,6 @@ export function makeTempDirSync({ return path!; } -// mkdir creates a new directory with the specified name -// and permission bits (before umask). -export function mkdirSync(path: string, mode = 0o777): void { - /* Ideally we could write: - const res = sendSync({ - command: fbs.Command.MKDIR_SYNC, - mkdirSyncPath: path, - mkdirSyncMode: mode, - }); - */ - const builder = new flatbuffers.Builder(); - const path_ = builder.createString(path); - fbs.MkdirSync.startMkdirSync(builder); - fbs.MkdirSync.addPath(builder, path_); - fbs.MkdirSync.addMode(builder, mode); - const msg = fbs.MkdirSync.endMkdirSync(builder); - sendSync(builder, fbs.Any.MkdirSync, msg); -} - 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 544d7d49f0..df88b50850 100644 --- a/js/os_test.ts +++ b/js/os_test.ts @@ -152,25 +152,6 @@ test(function makeTempDirSyncPerm() { assertEqual(err.name, "PermissionDenied"); }); -testPerm({ write: true }, function mkdirSync() { - const path = deno.makeTempDirSync() + "/dir/subdir"; - deno.mkdirSync(path); - const pathInfo = deno.statSync(path); - assert(pathInfo.isDirectory()); -}); - -testPerm({ write: false }, function mkdDirSyncPerm() { - let err; - try { - const path = "/baddir"; - deno.mkdirSync(path); - } catch (err_) { - err = err_; - } - assertEqual(err.kind, deno.ErrorKind.PermissionDenied); - assertEqual(err.name, "PermissionDenied"); -}); - testPerm({ write: true }, function renameSync() { const testDir = deno.makeTempDirSync() + "/test-rename"; const oldpath = testDir + "/oldpath"; diff --git a/js/unit_tests.ts b/js/unit_tests.ts index efbc7383c7..1c5a9227e3 100644 --- a/js/unit_tests.ts +++ b/js/unit_tests.ts @@ -6,3 +6,4 @@ import "./console_test.ts"; import "./fetch_test.ts"; import "./os_test.ts"; import "./read_file_test.ts"; +import "./mkdir_test.ts"; diff --git a/src/handlers.rs b/src/handlers.rs index 2fff5a06f1..7d8fafc10b 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -49,7 +49,7 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) { msg::Any::TimerStart => handle_timer_start, msg::Any::TimerClear => handle_timer_clear, msg::Any::MakeTempDir => handle_make_temp_dir, - msg::Any::MkdirSync => handle_mkdir_sync, + msg::Any::Mkdir => handle_mkdir, msg::Any::ReadFile => handle_read_file, msg::Any::RenameSync => handle_rename_sync, msg::Any::SetEnv => handle_set_env, @@ -418,18 +418,17 @@ fn handle_make_temp_dir(d: *const DenoC, base: &msg::Base) -> Box { }())) } -fn handle_mkdir_sync(d: *const DenoC, base: &msg::Base) -> Box { - let msg = base.msg_as_mkdir_sync().unwrap(); - let path = msg.path().unwrap(); +fn handle_mkdir(d: *const DenoC, base: &msg::Base) -> Box { + let msg = base.msg_as_mkdir().unwrap(); // TODO let mode = msg.mode(); + let path = msg.path().unwrap(); let deno = from_c(d); - debug!("handle_mkdir_sync {}", path); if !deno.flags.allow_write { return odd_future(permission_denied()); } - - // TODO(ry) use blocking + // TODO Use tokio_threadpool. Box::new(futures::future::result(|| -> OpResult { + debug!("handle_mkdir {}", path); // TODO(ry) Use mode. deno_fs::mkdir(Path::new(path))?; Ok(None) diff --git a/src/msg.fbs b/src/msg.fbs index 77aae8ffb6..33278a6698 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -14,7 +14,7 @@ union Any { FetchRes, MakeTempDir, MakeTempDirRes, - MkdirSync, + Mkdir, ReadFile, ReadFileRes, RenameSync, @@ -167,7 +167,7 @@ table MakeTempDirRes { path: string; } -table MkdirSync { +table Mkdir { path: string; mode: uint; // mode specified by https://godoc.org/os#FileMode