mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
Implement deno.readlink() (#797)
This commit is contained in:
parent
d957f8ebc2
commit
ad5065e23e
7 changed files with 133 additions and 1 deletions
1
BUILD.gn
1
BUILD.gn
|
@ -83,6 +83,7 @@ ts_sources = [
|
||||||
"js/read_file.ts",
|
"js/read_file.ts",
|
||||||
"js/remove.ts",
|
"js/remove.ts",
|
||||||
"js/rename.ts",
|
"js/rename.ts",
|
||||||
|
"js/read_link.ts",
|
||||||
"js/stat.ts",
|
"js/stat.ts",
|
||||||
"js/symlink.ts",
|
"js/symlink.ts",
|
||||||
"js/text_encoding.ts",
|
"js/text_encoding.ts",
|
||||||
|
|
|
@ -5,8 +5,9 @@ export { env, exit } from "./os";
|
||||||
export { mkdirSync, mkdir } from "./mkdir";
|
export { mkdirSync, mkdir } from "./mkdir";
|
||||||
export { makeTempDirSync, makeTempDir } from "./make_temp_dir";
|
export { makeTempDirSync, makeTempDir } from "./make_temp_dir";
|
||||||
export { removeSync, remove, removeAllSync, removeAll } from "./remove";
|
export { removeSync, remove, removeAllSync, removeAll } from "./remove";
|
||||||
export { readFileSync, readFile } from "./read_file";
|
|
||||||
export { renameSync, rename } from "./rename";
|
export { renameSync, rename } from "./rename";
|
||||||
|
export { readFileSync, readFile } from "./read_file";
|
||||||
|
export { readlinkSync, readlink } from "./read_link";
|
||||||
export { FileInfo, statSync, lstatSync, stat, lstat } from "./stat";
|
export { FileInfo, statSync, lstatSync, stat, lstat } from "./stat";
|
||||||
export { symlinkSync, symlink } from "./symlink";
|
export { symlinkSync, symlink } from "./symlink";
|
||||||
export { writeFileSync, writeFile } from "./write_file";
|
export { writeFileSync, writeFile } from "./write_file";
|
||||||
|
|
46
js/read_link.ts
Normal file
46
js/read_link.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import * as fbs from "gen/msg_generated";
|
||||||
|
import { flatbuffers } from "flatbuffers";
|
||||||
|
import { assert } from "./util";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the destination of the named symbolic link synchronously.
|
||||||
|
*
|
||||||
|
* import { readlinkSync } from "deno";
|
||||||
|
* const targetPath = readlinkSync("symlink/path");
|
||||||
|
*/
|
||||||
|
export function readlinkSync(name: string): string {
|
||||||
|
return res(dispatch.sendSync(...req(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the destination of the named symbolic link.
|
||||||
|
*
|
||||||
|
* import { readlink } from "deno";
|
||||||
|
* const targetPath = await readlink("symlink/path");
|
||||||
|
*/
|
||||||
|
export async function readlink(name: string): Promise<string> {
|
||||||
|
return res(await dispatch.sendAsync(...req(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function req(
|
||||||
|
name: string
|
||||||
|
): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] {
|
||||||
|
const builder = new flatbuffers.Builder();
|
||||||
|
const name_ = builder.createString(name);
|
||||||
|
fbs.Readlink.startReadlink(builder);
|
||||||
|
fbs.Readlink.addName(builder, name_);
|
||||||
|
const msg = fbs.Readlink.endReadlink(builder);
|
||||||
|
return [builder, fbs.Any.Readlink, msg];
|
||||||
|
}
|
||||||
|
|
||||||
|
function res(baseRes: null | fbs.Base): string {
|
||||||
|
assert(baseRes !== null);
|
||||||
|
assert(fbs.Any.ReadlinkRes === baseRes!.msgType());
|
||||||
|
const res = new fbs.ReadlinkRes();
|
||||||
|
assert(baseRes!.msg(res) !== null);
|
||||||
|
const path = res.path();
|
||||||
|
assert(path !== null);
|
||||||
|
return path!;
|
||||||
|
}
|
44
js/read_link_test.ts
Normal file
44
js/read_link_test.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// 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 readlinkSyncSuccess() {
|
||||||
|
const testDir = deno.makeTempDirSync() + "/test-readlink-sync";
|
||||||
|
const target = testDir + "/target";
|
||||||
|
const symlink = testDir + "/symln";
|
||||||
|
deno.mkdirSync(target);
|
||||||
|
// TODO Add test for Windows once symlink is implemented for Windows.
|
||||||
|
// See https://github.com/denoland/deno/issues/815.
|
||||||
|
if (deno.platform !== "win32") {
|
||||||
|
deno.symlinkSync(target, symlink);
|
||||||
|
const targetPath = deno.readlinkSync(symlink);
|
||||||
|
assertEqual(targetPath, target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test(function readlinkSyncNotFound() {
|
||||||
|
let caughtError = false;
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
data = deno.readlinkSync("bad_filename");
|
||||||
|
} catch (e) {
|
||||||
|
caughtError = true;
|
||||||
|
assertEqual(e.kind, deno.ErrorKind.NotFound);
|
||||||
|
}
|
||||||
|
assert(caughtError);
|
||||||
|
assertEqual(data, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: true }, async function readlinkSuccess() {
|
||||||
|
const testDir = deno.makeTempDirSync() + "/test-readlink";
|
||||||
|
const target = testDir + "/target";
|
||||||
|
const symlink = testDir + "/symln";
|
||||||
|
deno.mkdirSync(target);
|
||||||
|
// TODO Add test for Windows once symlink is implemented for Windows.
|
||||||
|
// See https://github.com/denoland/deno/issues/815.
|
||||||
|
if (deno.platform !== "win32") {
|
||||||
|
deno.symlinkSync(target, symlink);
|
||||||
|
const targetPath = await deno.readlink(symlink);
|
||||||
|
assertEqual(targetPath, target);
|
||||||
|
}
|
||||||
|
});
|
|
@ -11,6 +11,7 @@ import "./mkdir_test.ts";
|
||||||
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";
|
||||||
|
import "./read_link_test.ts";
|
||||||
import "./blob_test.ts";
|
import "./blob_test.ts";
|
||||||
import "./timers_test.ts";
|
import "./timers_test.ts";
|
||||||
import "./symlink_test.ts";
|
import "./symlink_test.ts";
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub extern "C" fn msg_from_js(i: *const isolate, buf: deno_buf) {
|
||||||
msg::Any::Remove => handle_remove,
|
msg::Any::Remove => handle_remove,
|
||||||
msg::Any::ReadFile => handle_read_file,
|
msg::Any::ReadFile => handle_read_file,
|
||||||
msg::Any::Rename => handle_rename,
|
msg::Any::Rename => handle_rename,
|
||||||
|
msg::Any::Readlink => handle_read_link,
|
||||||
msg::Any::Symlink => handle_symlink,
|
msg::Any::Symlink => handle_symlink,
|
||||||
msg::Any::SetEnv => handle_set_env,
|
msg::Any::SetEnv => handle_set_env,
|
||||||
msg::Any::Stat => handle_stat,
|
msg::Any::Stat => handle_stat,
|
||||||
|
@ -702,3 +703,31 @@ fn handle_symlink(i: *const isolate, base: &msg::Base) -> Box<Op> {
|
||||||
}()))
|
}()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_read_link(_i: *const isolate, base: &msg::Base) -> Box<Op> {
|
||||||
|
let msg = base.msg_as_readlink().unwrap();
|
||||||
|
let cmd_id = base.cmd_id();
|
||||||
|
let name = String::from(msg.name().unwrap());
|
||||||
|
Box::new(futures::future::result(|| -> OpResult {
|
||||||
|
debug!("handle_read_link {}", name);
|
||||||
|
let path = fs::read_link(Path::new(&name))?;
|
||||||
|
let builder = &mut FlatBufferBuilder::new();
|
||||||
|
let path_off = builder.create_string(path.to_str().unwrap());
|
||||||
|
let msg = msg::ReadlinkRes::create(
|
||||||
|
builder,
|
||||||
|
&msg::ReadlinkResArgs {
|
||||||
|
path: Some(path_off),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Ok(serialize_response(
|
||||||
|
cmd_id,
|
||||||
|
builder,
|
||||||
|
msg::BaseArgs {
|
||||||
|
msg: Some(msg.as_union_value()),
|
||||||
|
msg_type: msg::Any::ReadlinkRes,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}()))
|
||||||
|
}
|
||||||
|
|
10
src/msg.fbs
10
src/msg.fbs
|
@ -20,6 +20,8 @@ union Any {
|
||||||
ReadFileRes,
|
ReadFileRes,
|
||||||
WriteFile,
|
WriteFile,
|
||||||
Rename,
|
Rename,
|
||||||
|
Readlink,
|
||||||
|
ReadlinkRes,
|
||||||
Symlink,
|
Symlink,
|
||||||
Stat,
|
Stat,
|
||||||
StatRes,
|
StatRes,
|
||||||
|
@ -202,6 +204,14 @@ table Rename {
|
||||||
newpath: string;
|
newpath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table Readlink {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
table ReadlinkRes {
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
table Symlink {
|
table Symlink {
|
||||||
oldname: string;
|
oldname: string;
|
||||||
newname: string;
|
newname: string;
|
||||||
|
|
Loading…
Add table
Reference in a new issue