1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00

Implement writeFileSync

In collaboration with Tommy Savaria <tommy.savaria@protonmail.ch>
This commit is contained in:
Ryan Dahl 2018-08-22 13:19:32 -04:00
parent e7cab71574
commit 7d7263c48f
6 changed files with 89 additions and 6 deletions

View file

@ -1,4 +1,4 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
// Public deno module.
export { exit, readFileSync } from "./os";
export { exit, readFileSync, writeFileSync } from "./os";
export { libdeno } from "./globals";

View file

@ -121,15 +121,32 @@ export function readFileSync(filename: string): Uint8Array {
export function writeFileSync(
filename: string,
data: Uint8Array,
perm: number
perm = 0o666
): void {
util.notImplemented();
/*
pubInternal("os", {
/* Ideally we could write:
const res = send({
command: fbs.Command.WRITE_FILE_SYNC,
writeFileSyncFilename: filename,
writeFileSyncData: data,
writeFileSyncPerm: perm
});
*/
const builder = new flatbuffers.Builder();
const filename_ = builder.createString(filename);
const dataOffset = fbs.WriteFileSync.createDataVector(builder, data);
fbs.WriteFileSync.startWriteFileSync(builder);
fbs.WriteFileSync.addFilename(builder, filename_);
fbs.WriteFileSync.addData(builder, dataOffset);
fbs.WriteFileSync.addPerm(builder, perm);
const msg = fbs.WriteFileSync.endWriteFileSync(builder);
fbs.Base.startBase(builder);
fbs.Base.addMsg(builder, msg);
fbs.Base.addMsgType(builder, fbs.Any.WriteFileSync);
builder.finish(fbs.Base.endBase(builder));
const resBuf = libdeno.send(builder.asUint8Array());
if (resBuf != null) {
const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!));
const baseRes = fbs.Base.getRootAsBase(bb);
maybeThrowError(baseRes);
}
}

View file

@ -5,6 +5,7 @@
import { test, assert, assertEqual } from "./testing/testing.ts";
import { readFileSync } from "deno";
import * as deno from "deno";
import "./compiler_test.ts";
@ -109,6 +110,35 @@ test(function tests_readFileSync_NotFound() {
});
*/
/* TODO(ry) Add this once we can create a tmpDir to write the file into.
test(function writeFileSyncSuccess() {
const enc = new TextEncoder();
const dataWritten = enc.encode("Hello");
const filename = "TEMPDIR/test.txt";
deno.writeFileSync(filename, dataWritten, 0o666);
const dataRead = readFileSync(filename);
assertEqual(dataRead, dataWritten);
});
*/
// For this test to pass we need --allow-write permission.
// Otherwise it will fail with deno.PermissionDenied instead of deno.NotFound.
test(function writeFileSyncFail() {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = "/baddir/test.txt";
// The following should fail because /baddir doesn't exist (hopefully).
let caughtError = false;
try {
deno.writeFileSync(filename, data);
} catch (e) {
caughtError = true;
// TODO assertEqual(e, deno.NotFound);
assertEqual(e.name, "deno.NotFound");
}
assert(caughtError);
});
test(async function tests_fetch() {
const response = await fetch("http://localhost:4545/package.json");
const json = await response.json();

View file

@ -1,6 +1,7 @@
use std;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::Path;
pub fn read_file_sync(path: &Path) -> std::io::Result<Vec<u8>> {
@ -17,6 +18,11 @@ pub fn read_file_sync_string(path: &Path) -> std::io::Result<String> {
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))
}
pub fn write_file_sync(path: &Path, content: &[u8]) -> std::io::Result<()> {
let mut f = File::create(path)?;
f.write_all(content)
}
pub fn mkdir(path: &Path) -> std::io::Result<()> {
debug!("mkdir -p {}", path.display());
assert!(path.has_root(), "non-has_root not yet implemented");

View file

@ -70,6 +70,14 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) {
let filename = msg.filename().unwrap();
handle_read_file_sync(d, &mut builder, filename)
}
msg::Any::WriteFileSync => {
// TODO base.msg_as_WriteFileSync();
let msg = msg::WriteFileSync::init_from_table(base.msg().unwrap());
let filename = msg.filename().unwrap();
let data = msg.data().unwrap();
let perm = msg.perm();
handle_write_file_sync(d, &mut builder, filename, data, perm)
}
_ => panic!(format!(
"Unhandled message {}",
msg::enum_name_any(msg_type)
@ -413,6 +421,28 @@ fn handle_read_file_sync(
))
}
fn handle_write_file_sync(
d: *const DenoC,
builder: &mut FlatBufferBuilder,
filename: &str,
data: &[u8],
perm: u32,
) -> HandlerResult {
debug!("handle_write_file_sync {}", filename);
let deno = from_c(d);
if deno.flags.allow_write {
// TODO(ry) Use perm.
fs::write_file_sync(Path::new(filename), data)?;
Ok(null_buf())
} else {
let err = std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
"allow_write is off.",
);
Err(err.into())
}
}
// TODO(ry) Use Deno instead of DenoC as first arg.
fn remove_timer(d: *const DenoC, timer_id: u32) {
let deno = from_c(d);

View file

@ -41,7 +41,7 @@ def main(argv):
deno_exe = os.path.join(build_dir, "deno" + executable_suffix)
check_exists(deno_exe)
run([deno_exe, "js/unit_tests.ts"])
run([deno_exe, "js/unit_tests.ts", "--allow-write"])
check_exists(deno_exe)
check_output_test(deno_exe)