1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-22 06:09:25 -05:00

Implemented statSync and lStatSync

This commit is contained in:
Aaron Power 2018-08-29 14:22:25 +01:00 committed by Ryan Dahl
parent d8d5c421c3
commit b86bf4d8a4
5 changed files with 219 additions and 1 deletions

View file

@ -1,5 +1,13 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
// Public deno module.
export { exit, makeTempDirSync, readFileSync, writeFileSync } from "./os";
export {
exit,
FileInfo,
makeTempDirSync,
readFileSync,
statSync,
lStatSync,
writeFileSync
} from "./os";
export { libdeno } from "./libdeno";
export const argv: string[] = [];

View file

@ -169,6 +169,81 @@ export function readFileSync(filename: string): Uint8Array {
return new Uint8Array(dataArray!);
}
export class FileInfo {
private _isFile: boolean;
private _isSymlink: boolean;
len: number;
modified: number;
accessed: number;
// Creation time is not available on all platforms.
created: number | null;
/* @internal */
constructor(private _msg: fbs.StatSyncRes) {
const created = this._msg.created().toFloat64();
this._isFile = this._msg.isFile();
this._isSymlink = this._msg.isSymlink();
this.len = this._msg.len().toFloat64();
this.modified = this._msg.modified().toFloat64();
this.accessed = this._msg.accessed().toFloat64();
this.created = created ? created: null;
}
isFile() {
return this._isFile;
}
isDirectory() {
return !this._isFile && !this._isSymlink;
}
isSymlink() {
return this._isSymlink;
}
}
export function lStatSync(filename: string): FileInfo {
return statSyncInner(filename, true);
}
export function statSync(filename: string): FileInfo {
return statSyncInner(filename, false);
}
function statSyncInner(filename: string, lstat: boolean): FileInfo {
/* Ideally we could write
const res = send({
command: fbs.Command.STAT_FILE_SYNC,
StatFilename: filename,
StatLStat: lstat,
});
return new FileInfo(res);
*/
const builder = new flatbuffers.Builder();
const filename_ = builder.createString(filename);
fbs.StatSync.startStatSync(builder);
fbs.StatSync.addFilename(builder, filename_);
fbs.StatSync.addLstat(builder, lstat);
const msg = fbs.StatSync.endStatSync(builder);
fbs.Base.startBase(builder);
fbs.Base.addMsg(builder, msg);
fbs.Base.addMsgType(builder, fbs.Any.StatSync);
builder.finish(fbs.Base.endBase(builder));
const resBuf = libdeno.send(builder.asUint8Array());
assert(resBuf != null);
// TypeScript does not track `assert` from a CFA perspective, therefore not
// null assertion `!`
const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!));
const baseRes = fbs.Base.getRootAsBase(bb);
maybeThrowError(baseRes);
assert(fbs.Any.StatSyncRes === baseRes.msgType());
const res = new fbs.StatSyncRes();
assert(baseRes.msg(res) != null);
// TypeScript cannot track assertion above, therefore not null assertion
return new FileInfo(baseRes.msg(res)!);
}
export function writeFileSync(
filename: string,
data: Uint8Array,

View file

@ -13,6 +13,70 @@ test(async function tests_test() {
assert(true);
});
// TODO Add tests for modified, accessed, and created fields once there is a way
// to create temp files.
test(async function statSyncSuccess() {
const packageInfo = deno.statSync("package.json");
assert(packageInfo.isFile());
assert(!packageInfo.isSymlink());
const testingInfo = deno.statSync("testing");
assert(testingInfo.isDirectory());
assert(!testingInfo.isSymlink());
const srcInfo = deno.statSync("src");
assert(srcInfo.isDirectory());
assert(!srcInfo.isSymlink());
})
test(async function statSyncNotFound() {
let caughtError = false;
let badInfo;
try {
badInfo = deno.statSync("bad_file_name");
} catch (err) {
caughtError = true;
// TODO assert(err instanceof deno.NotFound).
assert(err);
assertEqual(err.name, "deno.NotFound");
}
assert(caughtError);
assertEqual(badInfo, undefined);
});
test(async function lStatSyncSuccess() {
const packageInfo = deno.lStatSync("package.json");
assert(packageInfo.isFile());
assert(!packageInfo.isSymlink());
const testingInfo = deno.lStatSync("testing");
assert(!testingInfo.isDirectory());
assert(testingInfo.isSymlink());
const srcInfo = deno.lStatSync("src");
assert(srcInfo.isDirectory());
assert(!srcInfo.isSymlink());
})
test(async function lStatSyncNotFound() {
let caughtError = false;
let badInfo;
try {
badInfo = deno.lStatSync("bad_file_name");
} catch (err) {
caughtError = true;
// TODO assert(err instanceof deno.NotFound).
assert(err);
assertEqual(err.name, "deno.NotFound");
}
assert(caughtError);
assertEqual(badInfo, undefined);
});
test(async function tests_readFileSync() {
const data = deno.readFileSync("package.json");
if (!data.byteLength) {

View file

@ -14,6 +14,7 @@ use hyper::Client;
use msg_generated::deno as msg;
use std;
use std::fs;
use std::time::UNIX_EPOCH;
use std::path::Path;
use std::time::{Duration, Instant};
use tokio::prelude::future;
@ -78,6 +79,13 @@ 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::StatSync => {
// TODO base.msg_as_StatSync();
let msg = msg::StatSync::init_from_table(base.msg().unwrap());
let filename = msg.filename().unwrap();
let lstat = msg.lstat();
handle_stat_sync(d, &mut builder, filename, lstat)
}
msg::Any::WriteFileSync => {
// TODO base.msg_as_WriteFileSync();
let msg = msg::WriteFileSync::init_from_table(base.msg().unwrap());
@ -467,6 +475,53 @@ fn handle_read_file_sync(
))
}
macro_rules! to_seconds {
($time:expr) => {{
// Unwrap is safe here as if the file is before the unix epoch
// something is very wrong.
$time.and_then(|t| Ok(t.duration_since(UNIX_EPOCH).unwrap().as_secs()))
.unwrap_or(0)
}}
}
fn handle_stat_sync(
_d: *const DenoC,
builder: &mut FlatBufferBuilder,
filename: &str,
lstat: bool,
) -> HandlerResult {
debug!("handle_stat_sync {} {}", filename, lstat);
let path = Path::new(filename);
let metadata = if lstat {
fs::symlink_metadata(path)?
} else {
fs::metadata(path)?
};
let msg = msg::StatSyncRes::create(
builder,
&msg::StatSyncResArgs {
is_file: metadata.is_file(),
is_symlink: metadata.file_type().is_symlink(),
len: metadata.len(),
modified: to_seconds!(metadata.modified()),
accessed: to_seconds!(metadata.accessed()),
created: to_seconds!(metadata.created()),
..Default::default()
},
);
Ok(create_msg(
builder,
&msg::BaseArgs {
msg: Some(flatbuffers::Offset::new(msg.value())),
msg_type: msg::Any::StatSyncRes,
..Default::default()
},
))
}
fn handle_write_file_sync(
d: *const DenoC,
_builder: &mut FlatBufferBuilder,

View file

@ -16,6 +16,8 @@ union Any {
MakeTempDirRes,
ReadFileSync,
ReadFileSyncRes,
StatSync,
StatSyncRes,
WriteFileSync,
}
@ -153,6 +155,20 @@ table ReadFileSyncRes {
data: [ubyte];
}
table StatSync {
filename: string;
lstat: bool;
}
table StatSyncRes {
is_file: bool;
is_symlink: bool;
len: ulong;
modified:ulong;
accessed:ulong;
created:ulong;
}
table WriteFileSync {
filename: string;
data: [ubyte];