mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 20:25:12 -05:00
Implemented statSync and lStatSync
This commit is contained in:
parent
d8d5c421c3
commit
b86bf4d8a4
5 changed files with 219 additions and 1 deletions
10
js/deno.ts
10
js/deno.ts
|
@ -1,5 +1,13 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
// Public deno module.
|
// 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 { libdeno } from "./libdeno";
|
||||||
export const argv: string[] = [];
|
export const argv: string[] = [];
|
||||||
|
|
75
js/os.ts
75
js/os.ts
|
@ -169,6 +169,81 @@ export function readFileSync(filename: string): Uint8Array {
|
||||||
return new Uint8Array(dataArray!);
|
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(
|
export function writeFileSync(
|
||||||
filename: string,
|
filename: string,
|
||||||
data: Uint8Array,
|
data: Uint8Array,
|
||||||
|
|
|
@ -13,6 +13,70 @@ test(async function tests_test() {
|
||||||
assert(true);
|
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() {
|
test(async function tests_readFileSync() {
|
||||||
const data = deno.readFileSync("package.json");
|
const data = deno.readFileSync("package.json");
|
||||||
if (!data.byteLength) {
|
if (!data.byteLength) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ use hyper::Client;
|
||||||
use msg_generated::deno as msg;
|
use msg_generated::deno as msg;
|
||||||
use std;
|
use std;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::time::UNIX_EPOCH;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::prelude::future;
|
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();
|
let filename = msg.filename().unwrap();
|
||||||
handle_read_file_sync(d, &mut builder, filename)
|
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 => {
|
msg::Any::WriteFileSync => {
|
||||||
// TODO base.msg_as_WriteFileSync();
|
// TODO base.msg_as_WriteFileSync();
|
||||||
let msg = msg::WriteFileSync::init_from_table(base.msg().unwrap());
|
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(
|
fn handle_write_file_sync(
|
||||||
d: *const DenoC,
|
d: *const DenoC,
|
||||||
_builder: &mut FlatBufferBuilder,
|
_builder: &mut FlatBufferBuilder,
|
||||||
|
|
16
src/msg.fbs
16
src/msg.fbs
|
@ -16,6 +16,8 @@ union Any {
|
||||||
MakeTempDirRes,
|
MakeTempDirRes,
|
||||||
ReadFileSync,
|
ReadFileSync,
|
||||||
ReadFileSyncRes,
|
ReadFileSyncRes,
|
||||||
|
StatSync,
|
||||||
|
StatSyncRes,
|
||||||
WriteFileSync,
|
WriteFileSync,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +155,20 @@ table ReadFileSyncRes {
|
||||||
data: [ubyte];
|
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 {
|
table WriteFileSync {
|
||||||
filename: string;
|
filename: string;
|
||||||
data: [ubyte];
|
data: [ubyte];
|
||||||
|
|
Loading…
Add table
Reference in a new issue