mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
Implement deno.rename() (#731)
This commit is contained in:
parent
26081a32df
commit
88d42f0b18
9 changed files with 118 additions and 65 deletions
2
BUILD.gn
2
BUILD.gn
|
@ -199,6 +199,7 @@ run_node("gen_declarations") {
|
|||
"js/mkdir.ts",
|
||||
"js/os.ts",
|
||||
"js/read_file.ts",
|
||||
"js/rename.ts",
|
||||
"js/remove.ts",
|
||||
"js/stat.ts",
|
||||
"js/text_encoding.ts",
|
||||
|
@ -242,6 +243,7 @@ run_node("bundle") {
|
|||
"js/os.ts",
|
||||
"js/plugins.d.ts",
|
||||
"js/read_file.ts",
|
||||
"js/rename.ts",
|
||||
"js/remove.ts",
|
||||
"js/stat.ts",
|
||||
"js/text_encoding.ts",
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||
// Public deno module.
|
||||
/// <amd-module name="deno"/>
|
||||
export { env, exit, makeTempDirSync, renameSync } from "./os";
|
||||
export {
|
||||
env,
|
||||
exit,
|
||||
makeTempDirSync
|
||||
} from "./os";
|
||||
export { mkdirSync, mkdir } from "./mkdir";
|
||||
export { removeSync, remove, removeAllSync, removeAll } from "./remove";
|
||||
export { readFileSync, readFile } from "./read_file";
|
||||
export { renameSync, rename } from "./rename";
|
||||
export { FileInfo, statSync, lstatSync, stat, lstat } from "./stat";
|
||||
export { writeFileSync, writeFile } from "./write_file";
|
||||
export { ErrorKind, DenoError } from "./errors";
|
||||
|
|
19
js/os.ts
19
js/os.ts
|
@ -164,22 +164,3 @@ export function env(): { [index: string]: string } {
|
|||
// TypeScript cannot track assertion above, therefore not null assertion
|
||||
return createEnv(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames (moves) oldpath to newpath.
|
||||
* import { renameSync } from "deno";
|
||||
* const oldpath = 'from/path';
|
||||
* const newpath = 'to/path';
|
||||
*
|
||||
* renameSync(oldpath, newpath);
|
||||
*/
|
||||
export function renameSync(oldpath: string, newpath: string): void {
|
||||
const builder = new flatbuffers.Builder();
|
||||
const _oldpath = builder.createString(oldpath);
|
||||
const _newpath = builder.createString(newpath);
|
||||
fbs.RenameSync.startRenameSync(builder);
|
||||
fbs.RenameSync.addOldpath(builder, _oldpath);
|
||||
fbs.RenameSync.addNewpath(builder, _newpath);
|
||||
const msg = fbs.RenameSync.endRenameSync(builder);
|
||||
sendSync(builder, fbs.Any.RenameSync, msg);
|
||||
}
|
||||
|
|
|
@ -60,40 +60,3 @@ test(function makeTempDirSyncPerm() {
|
|||
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";
|
||||
const newpath = testDir + "/newpath";
|
||||
deno.mkdirSync(oldpath);
|
||||
deno.renameSync(oldpath, newpath);
|
||||
const newPathInfo = deno.statSync(newpath);
|
||||
assert(newPathInfo.isDirectory());
|
||||
|
||||
let caughtErr = false;
|
||||
let oldPathInfo;
|
||||
|
||||
try {
|
||||
oldPathInfo = deno.statSync(oldpath);
|
||||
} catch (err) {
|
||||
caughtErr = true;
|
||||
assertEqual(err.kind, deno.ErrorKind.NotFound);
|
||||
assertEqual(err.name, "NotFound");
|
||||
}
|
||||
|
||||
assert(caughtErr);
|
||||
assertEqual(oldPathInfo, undefined);
|
||||
});
|
||||
|
||||
test(function renameSyncPerm() {
|
||||
let err;
|
||||
try {
|
||||
const oldpath = "/oldbaddir";
|
||||
const newpath = "/newbaddir";
|
||||
deno.renameSync(oldpath, newpath);
|
||||
} catch (err_) {
|
||||
err = err_;
|
||||
}
|
||||
assertEqual(err.kind, deno.ErrorKind.PermissionDenied);
|
||||
assertEqual(err.name, "PermissionDenied");
|
||||
});
|
||||
|
|
42
js/rename.ts
Normal file
42
js/rename.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
// 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";
|
||||
|
||||
/**
|
||||
* Synchronously renames (moves) oldpath to newpath. If newpath already exists
|
||||
* and is not a directory, Rename replaces it. OS-specific restrictions may
|
||||
* apply when oldpath and newpath are in different directories.
|
||||
*
|
||||
* import { renameSync } from "deno";
|
||||
* renameSync("old/path", "new/path");
|
||||
*/
|
||||
export function renameSync(oldpath: string, newpath: string): void {
|
||||
dispatch.sendSync(...req(oldpath, newpath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames (moves) oldpath to newpath. If newpath already exists
|
||||
* and is not a directory, Rename replaces it. OS-specific restrictions may
|
||||
* apply when oldpath and newpath are in different directories.
|
||||
*
|
||||
* import { rename } from "deno";
|
||||
* await rename("old/path", "new/path");
|
||||
*/
|
||||
export async function rename(oldpath: string, newpath: string): Promise<void> {
|
||||
await dispatch.sendAsync(...req(oldpath, newpath));
|
||||
}
|
||||
|
||||
function req(
|
||||
oldpath: string,
|
||||
newpath: string
|
||||
): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] {
|
||||
const builder = new flatbuffers.Builder();
|
||||
const oldpath_ = builder.createString(oldpath);
|
||||
const newpath_ = builder.createString(newpath);
|
||||
fbs.Rename.startRename(builder);
|
||||
fbs.Rename.addOldpath(builder, oldpath_);
|
||||
fbs.Rename.addNewpath(builder, newpath_);
|
||||
const msg = fbs.Rename.endRename(builder);
|
||||
return [builder, fbs.Any.Rename, msg];
|
||||
}
|
60
js/rename_test.ts
Normal file
60
js/rename_test.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
// 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 renameSyncSuccess() {
|
||||
const testDir = deno.makeTempDirSync() + "/test-rename-sync";
|
||||
const oldpath = testDir + "/oldpath";
|
||||
const newpath = testDir + "/newpath";
|
||||
deno.mkdirSync(oldpath);
|
||||
deno.renameSync(oldpath, newpath);
|
||||
const newPathInfo = deno.statSync(newpath);
|
||||
assert(newPathInfo.isDirectory());
|
||||
|
||||
let caughtErr = false;
|
||||
let oldPathInfo;
|
||||
|
||||
try {
|
||||
oldPathInfo = deno.statSync(oldpath);
|
||||
} catch (e) {
|
||||
caughtErr = true;
|
||||
assertEqual(e.kind, deno.ErrorKind.NotFound);
|
||||
}
|
||||
assert(caughtErr);
|
||||
assertEqual(oldPathInfo, undefined);
|
||||
});
|
||||
|
||||
testPerm({ write: false }, function renameSyncPerm() {
|
||||
let err;
|
||||
try {
|
||||
const oldpath = "/oldbaddir";
|
||||
const newpath = "/newbaddir";
|
||||
deno.renameSync(oldpath, newpath);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
assertEqual(err.kind, deno.ErrorKind.PermissionDenied);
|
||||
assertEqual(err.name, "PermissionDenied");
|
||||
});
|
||||
|
||||
testPerm({ write: true }, async function renameSuccess() {
|
||||
const testDir = deno.makeTempDirSync() + "/test-rename";
|
||||
const oldpath = testDir + "/oldpath";
|
||||
const newpath = testDir + "/newpath";
|
||||
deno.mkdirSync(oldpath);
|
||||
await deno.rename(oldpath, newpath);
|
||||
const newPathInfo = deno.statSync(newpath);
|
||||
assert(newPathInfo.isDirectory());
|
||||
|
||||
let caughtErr = false;
|
||||
let oldPathInfo;
|
||||
|
||||
try {
|
||||
oldPathInfo = deno.statSync(oldpath);
|
||||
} catch (e) {
|
||||
caughtErr = true;
|
||||
assertEqual(e.kind, deno.ErrorKind.NotFound);
|
||||
}
|
||||
assert(caughtErr);
|
||||
assertEqual(oldPathInfo, undefined);
|
||||
});
|
|
@ -9,3 +9,4 @@ import "./read_file_test.ts";
|
|||
import "./write_file_test.ts";
|
||||
import "./mkdir_test.ts";
|
||||
import "./stat_test.ts";
|
||||
import "./rename_test.ts";
|
||||
|
|
|
@ -55,7 +55,7 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) {
|
|||
msg::Any::Mkdir => handle_mkdir,
|
||||
msg::Any::Remove => handle_remove,
|
||||
msg::Any::ReadFile => handle_read_file,
|
||||
msg::Any::RenameSync => handle_rename_sync,
|
||||
msg::Any::Rename => handle_rename,
|
||||
msg::Any::SetEnv => handle_set_env,
|
||||
msg::Any::Stat => handle_stat,
|
||||
msg::Any::WriteFile => handle_write_file,
|
||||
|
@ -633,15 +633,14 @@ fn handle_timer_clear(d: *const DenoC, base: &msg::Base) -> Box<Op> {
|
|||
ok_future(None)
|
||||
}
|
||||
|
||||
fn handle_rename_sync(d: *const DenoC, base: &msg::Base) -> Box<Op> {
|
||||
fn handle_rename(d: *const DenoC, base: &msg::Base) -> Box<Op> {
|
||||
let deno = from_c(d);
|
||||
if !deno.flags.allow_write {
|
||||
return Box::new(futures::future::err(permission_denied()));
|
||||
};
|
||||
let msg = base.msg_as_rename_sync().unwrap();
|
||||
return odd_future(permission_denied());
|
||||
}
|
||||
let msg = base.msg_as_rename().unwrap();
|
||||
let oldpath = String::from(msg.oldpath().unwrap());
|
||||
let newpath = String::from(msg.newpath().unwrap());
|
||||
// TODO use blocking()
|
||||
Box::new(futures::future::result(|| -> OpResult {
|
||||
debug!("handle_rename {} {}", oldpath, newpath);
|
||||
fs::rename(Path::new(&oldpath), Path::new(&newpath))?;
|
||||
|
|
|
@ -19,7 +19,7 @@ union Any {
|
|||
ReadFile,
|
||||
ReadFileRes,
|
||||
WriteFile,
|
||||
RenameSync,
|
||||
Rename,
|
||||
Stat,
|
||||
StatRes,
|
||||
SetEnv,
|
||||
|
@ -194,7 +194,7 @@ table WriteFile {
|
|||
// perm specified by https://godoc.org/os#FileMode
|
||||
}
|
||||
|
||||
table RenameSync {
|
||||
table Rename {
|
||||
oldpath: string;
|
||||
newpath: string;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue