mirror of
https://github.com/denoland/deno.git
synced 2025-09-27 12:49:10 +00:00
Add cwd() and chdir() (#907)
This commit is contained in:
parent
d92c99eaba
commit
bbf88c5295
7 changed files with 156 additions and 5 deletions
2
BUILD.gn
2
BUILD.gn
|
@ -72,6 +72,7 @@ ts_sources = [
|
||||||
"js/console.ts",
|
"js/console.ts",
|
||||||
"js/copy_file.ts",
|
"js/copy_file.ts",
|
||||||
"js/deno.ts",
|
"js/deno.ts",
|
||||||
|
"js/dir.ts",
|
||||||
"js/dispatch.ts",
|
"js/dispatch.ts",
|
||||||
"js/dom_types.ts",
|
"js/dom_types.ts",
|
||||||
"js/errors.ts",
|
"js/errors.ts",
|
||||||
|
@ -107,7 +108,6 @@ ts_sources = [
|
||||||
"js/util.ts",
|
"js/util.ts",
|
||||||
"js/v8_source_maps.ts",
|
"js/v8_source_maps.ts",
|
||||||
"js/write_file.ts",
|
"js/write_file.ts",
|
||||||
|
|
||||||
"tsconfig.json",
|
"tsconfig.json",
|
||||||
|
|
||||||
# Listing package.json and yarn.lock as sources ensures the bundle is rebuilt
|
# Listing package.json and yarn.lock as sources ensures the bundle is rebuilt
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Public deno module.
|
// Public deno module.
|
||||||
/// <amd-module name="deno"/>
|
/// <amd-module name="deno"/>
|
||||||
export { env, exit } from "./os";
|
export { env, exit } from "./os";
|
||||||
|
export { chdir, cwd } from "./dir";
|
||||||
export { File, open, stdin, stdout, stderr, read, write, close } from "./files";
|
export { File, open, stdin, stdout, stderr, read, write, close } from "./files";
|
||||||
export {
|
export {
|
||||||
copy,
|
copy,
|
||||||
|
|
37
js/dir.ts
Normal file
37
js/dir.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import * as msg from "gen/msg_generated";
|
||||||
|
import { assert } from "./util";
|
||||||
|
import { flatbuffers } from "flatbuffers";
|
||||||
|
import { sendSync } from "./dispatch";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cwd() Return a string representing the current working directory.
|
||||||
|
* If the current directory can be reached via multiple paths
|
||||||
|
* (due to symbolic links), cwd() may return
|
||||||
|
* any one of them.
|
||||||
|
* throws NotFound exception if directory not available
|
||||||
|
*/
|
||||||
|
export function cwd(): string {
|
||||||
|
const builder = new flatbuffers.Builder(0);
|
||||||
|
msg.Cwd.startCwd(builder);
|
||||||
|
const inner = msg.Cwd.endCwd(builder);
|
||||||
|
const baseRes = sendSync(builder, msg.Any.Cwd, inner);
|
||||||
|
assert(baseRes != null);
|
||||||
|
assert(msg.Any.CwdRes === baseRes!.innerType());
|
||||||
|
const res = new msg.CwdRes();
|
||||||
|
assert(baseRes!.inner(res) != null);
|
||||||
|
return res.cwd()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* chdir() Change the current working directory to path.
|
||||||
|
* throws NotFound exception if directory not available
|
||||||
|
*/
|
||||||
|
export function chdir(directory: string): void {
|
||||||
|
const builder = new flatbuffers.Builder();
|
||||||
|
const directory_ = builder.createString(directory);
|
||||||
|
msg.Chdir.startChdir(builder);
|
||||||
|
msg.Chdir.addDirectory(builder, directory_);
|
||||||
|
const inner = msg.Chdir.endChdir(builder);
|
||||||
|
sendSync(builder, msg.Any.Chdir, inner);
|
||||||
|
}
|
54
js/dir_test.ts
Normal file
54
js/dir_test.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import { test, testPerm, assert, assertEqual } from "./test_util.ts";
|
||||||
|
import * as deno from "deno";
|
||||||
|
|
||||||
|
test(function dirCwdNotNull() {
|
||||||
|
assert(deno.cwd() != null);
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: true }, function dirCwdChdirSuccess() {
|
||||||
|
const initialdir = deno.cwd();
|
||||||
|
const path = deno.makeTempDirSync();
|
||||||
|
deno.chdir(path);
|
||||||
|
const current = deno.cwd();
|
||||||
|
if (deno.platform.os === "mac") {
|
||||||
|
assertEqual(current, "/private" + path);
|
||||||
|
} else {
|
||||||
|
assertEqual(current, path);
|
||||||
|
}
|
||||||
|
deno.chdir(initialdir);
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: true }, function dirCwdError() {
|
||||||
|
// excluding windows since it throws resource busy, while removeSync
|
||||||
|
if (["linux", "mac"].includes(deno.platform.os)) {
|
||||||
|
const initialdir = deno.cwd();
|
||||||
|
const path = deno.makeTempDirSync();
|
||||||
|
deno.chdir(path);
|
||||||
|
deno.removeSync(path);
|
||||||
|
try {
|
||||||
|
deno.cwd();
|
||||||
|
throw Error("current directory removed, should throw error");
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof deno.DenoError) {
|
||||||
|
console.log(err.name === "NotFound");
|
||||||
|
} else {
|
||||||
|
throw Error("raised different exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deno.chdir(initialdir);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: true }, function dirChdirError() {
|
||||||
|
const path = deno.makeTempDirSync() + "test";
|
||||||
|
try {
|
||||||
|
deno.chdir(path);
|
||||||
|
throw Error("directory not available, should throw error");
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof deno.DenoError) {
|
||||||
|
console.log(err.name === "NotFound");
|
||||||
|
} else {
|
||||||
|
throw Error("raised different exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -11,6 +11,7 @@ import "./read_dir_test.ts";
|
||||||
import "./write_file_test.ts";
|
import "./write_file_test.ts";
|
||||||
import "./copy_file_test.ts";
|
import "./copy_file_test.ts";
|
||||||
import "./mkdir_test.ts";
|
import "./mkdir_test.ts";
|
||||||
|
import "./dir_test";
|
||||||
import "./make_temp_dir_test.ts";
|
import "./make_temp_dir_test.ts";
|
||||||
import "./stat_test.ts";
|
import "./stat_test.ts";
|
||||||
import "./rename_test.ts";
|
import "./rename_test.ts";
|
||||||
|
|
13
src/msg.fbs
13
src/msg.fbs
|
@ -41,6 +41,9 @@ union Any {
|
||||||
Accept,
|
Accept,
|
||||||
Dial,
|
Dial,
|
||||||
NewConn,
|
NewConn,
|
||||||
|
Chdir,
|
||||||
|
Cwd,
|
||||||
|
CwdRes,
|
||||||
Metrics,
|
Metrics,
|
||||||
MetricsRes,
|
MetricsRes,
|
||||||
}
|
}
|
||||||
|
@ -93,6 +96,12 @@ enum ErrorKind: byte {
|
||||||
HttpOther,
|
HttpOther,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table Cwd {}
|
||||||
|
|
||||||
|
table CwdRes {
|
||||||
|
cwd: string;
|
||||||
|
}
|
||||||
|
|
||||||
table Base {
|
table Base {
|
||||||
cmd_id: uint32;
|
cmd_id: uint32;
|
||||||
sync: bool = true; // TODO(ry) Change default to false.
|
sync: bool = true; // TODO(ry) Change default to false.
|
||||||
|
@ -135,6 +144,10 @@ table CodeCache {
|
||||||
output_code: string;
|
output_code: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table Chdir {
|
||||||
|
directory: string;
|
||||||
|
}
|
||||||
|
|
||||||
table SetTimeout {
|
table SetTimeout {
|
||||||
timeout: double;
|
timeout: double;
|
||||||
}
|
}
|
||||||
|
|
53
src/ops.rs
53
src/ops.rs
|
@ -101,6 +101,8 @@ pub fn dispatch(
|
||||||
msg::Any::Listen => op_listen,
|
msg::Any::Listen => op_listen,
|
||||||
msg::Any::Accept => op_accept,
|
msg::Any::Accept => op_accept,
|
||||||
msg::Any::Dial => op_dial,
|
msg::Any::Dial => op_dial,
|
||||||
|
msg::Any::Chdir => op_chdir,
|
||||||
|
msg::Any::Cwd => op_cwd,
|
||||||
msg::Any::Metrics => op_metrics,
|
msg::Any::Metrics => op_metrics,
|
||||||
_ => panic!(format!(
|
_ => panic!(format!(
|
||||||
"Unhandled message {}",
|
"Unhandled message {}",
|
||||||
|
@ -110,8 +112,7 @@ pub fn dispatch(
|
||||||
op_creator(isolate.state.clone(), &base, data)
|
op_creator(isolate.state.clone(), &base, data)
|
||||||
};
|
};
|
||||||
|
|
||||||
let boxed_op = Box::new(
|
let boxed_op = Box::new(op.or_else(move |err: DenoError| -> DenoResult<Buf> {
|
||||||
op.or_else(move |err: DenoError| -> DenoResult<Buf> {
|
|
||||||
debug!("op err {}", err);
|
debug!("op err {}", err);
|
||||||
// No matter whether we got an Err or Ok, we want a serialized message to
|
// No matter whether we got an Err or Ok, we want a serialized message to
|
||||||
// send back. So transform the DenoError into a deno_buf.
|
// send back. So transform the DenoError into a deno_buf.
|
||||||
|
@ -143,8 +144,7 @@ pub fn dispatch(
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}),
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"msg_from_js {} sync {}",
|
"msg_from_js {} sync {}",
|
||||||
|
@ -283,6 +283,20 @@ fn op_code_cache(
|
||||||
}()))
|
}()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn op_chdir(
|
||||||
|
_state: Arc<IsolateState>,
|
||||||
|
base: &msg::Base,
|
||||||
|
data: &'static mut [u8],
|
||||||
|
) -> Box<Op> {
|
||||||
|
assert_eq!(data.len(), 0);
|
||||||
|
let inner = base.inner_as_chdir().unwrap();
|
||||||
|
let directory = inner.directory().unwrap();
|
||||||
|
Box::new(futures::future::result(|| -> OpResult {
|
||||||
|
let _result = std::env::set_current_dir(&directory)?;
|
||||||
|
Ok(empty_buf())
|
||||||
|
}()))
|
||||||
|
}
|
||||||
|
|
||||||
fn op_set_timeout(
|
fn op_set_timeout(
|
||||||
isolate: &mut Isolate,
|
isolate: &mut Isolate,
|
||||||
base: &msg::Base,
|
base: &msg::Base,
|
||||||
|
@ -811,6 +825,37 @@ fn get_mode(_perm: fs::Permissions) -> u32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn op_cwd(
|
||||||
|
_state: Arc<IsolateState>,
|
||||||
|
base: &msg::Base,
|
||||||
|
data: &'static mut [u8],
|
||||||
|
) -> Box<Op> {
|
||||||
|
assert_eq!(data.len(), 0);
|
||||||
|
let cmd_id = base.cmd_id();
|
||||||
|
Box::new(futures::future::result(|| -> OpResult {
|
||||||
|
let path = std::env::current_dir()?;
|
||||||
|
let builder = &mut FlatBufferBuilder::new();
|
||||||
|
let cwd =
|
||||||
|
builder.create_string(&path.into_os_string().into_string().unwrap());
|
||||||
|
let inner = msg::CwdRes::create(
|
||||||
|
builder,
|
||||||
|
&msg::CwdResArgs {
|
||||||
|
cwd: Some(cwd),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Ok(serialize_response(
|
||||||
|
cmd_id,
|
||||||
|
builder,
|
||||||
|
msg::BaseArgs {
|
||||||
|
inner: Some(inner.as_union_value()),
|
||||||
|
inner_type: msg::Any::CwdRes,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}()))
|
||||||
|
}
|
||||||
|
|
||||||
fn op_stat(
|
fn op_stat(
|
||||||
_config: Arc<IsolateState>,
|
_config: Arc<IsolateState>,
|
||||||
base: &msg::Base,
|
base: &msg::Base,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue