mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat(unstable): add Deno.futime and Deno.futimeSync (#7266)
This commit is contained in:
parent
c82c3b982e
commit
32de714dc7
8 changed files with 179 additions and 2 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -348,6 +348,7 @@ dependencies = [
|
||||||
"dlopen",
|
"dlopen",
|
||||||
"dprint-plugin-typescript",
|
"dprint-plugin-typescript",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
|
"filetime",
|
||||||
"futures",
|
"futures",
|
||||||
"fwdansi",
|
"fwdansi",
|
||||||
"http",
|
"http",
|
||||||
|
@ -564,9 +565,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.10"
|
version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
|
checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
|
@ -42,6 +42,7 @@ dlopen = "0.1.8"
|
||||||
encoding_rs = "0.8.23"
|
encoding_rs = "0.8.23"
|
||||||
dprint-plugin-typescript = "0.30.2"
|
dprint-plugin-typescript = "0.30.2"
|
||||||
futures = "0.3.5"
|
futures = "0.3.5"
|
||||||
|
filetime = "0.2.12"
|
||||||
http = "0.2.1"
|
http = "0.2.1"
|
||||||
idna = "0.2.0"
|
idna = "0.2.0"
|
||||||
indexmap = "1.5.1"
|
indexmap = "1.5.1"
|
||||||
|
|
34
cli/dts/lib.deno.unstable.d.ts
vendored
34
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -1247,6 +1247,40 @@ declare namespace Deno {
|
||||||
export function createHttpClient(
|
export function createHttpClient(
|
||||||
options: CreateHttpClientOptions,
|
options: CreateHttpClientOptions,
|
||||||
): HttpClient;
|
): HttpClient;
|
||||||
|
|
||||||
|
/** **UNSTABLE**: needs investigation into high precision time.
|
||||||
|
*
|
||||||
|
* Synchronously changes the access (`atime`) and modification (`mtime`) times
|
||||||
|
* of a file stream resource referenced by `rid`. Given times are either in
|
||||||
|
* seconds (UNIX epoch time) or as `Date` objects.
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const file = Deno.openSync("file.txt", { create: true });
|
||||||
|
* Deno.futimeSync(file.rid, 1556495550, new Date());
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function futimeSync(
|
||||||
|
rid: number,
|
||||||
|
atime: number | Date,
|
||||||
|
mtime: number | Date,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
/** **UNSTABLE**: needs investigation into high precision time.
|
||||||
|
*
|
||||||
|
* Changes the access (`atime`) and modification (`mtime`) times of a file
|
||||||
|
* stream resource referenced by `rid`. Given times are either in seconds
|
||||||
|
* (UNIX epoch time) or as `Date` objects.
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const file = await Deno.open("file.txt", { create: true });
|
||||||
|
* await Deno.futime(file.rid, 1556495550, new Date());
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function futime(
|
||||||
|
rid: number,
|
||||||
|
atime: number | Date,
|
||||||
|
mtime: number | Date,
|
||||||
|
): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare function fetch(
|
declare function fetch(
|
||||||
|
|
|
@ -174,6 +174,12 @@ pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
|
||||||
|
|
||||||
i.register_op("op_cwd", s.stateful_json_op_sync(t, op_cwd));
|
i.register_op("op_cwd", s.stateful_json_op_sync(t, op_cwd));
|
||||||
|
|
||||||
|
i.register_op("op_futime_sync", s.stateful_json_op_sync(t, op_futime_sync));
|
||||||
|
i.register_op(
|
||||||
|
"op_futime_async",
|
||||||
|
s.stateful_json_op_async(t, op_futime_async),
|
||||||
|
);
|
||||||
|
|
||||||
i.register_op("op_utime_sync", s.stateful_json_op_sync(t, op_utime_sync));
|
i.register_op("op_utime_sync", s.stateful_json_op_sync(t, op_utime_sync));
|
||||||
i.register_op(
|
i.register_op(
|
||||||
"op_utime_async",
|
"op_utime_async",
|
||||||
|
@ -1673,6 +1679,65 @@ async fn op_make_temp_file_async(
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct FutimeArgs {
|
||||||
|
rid: i32,
|
||||||
|
atime: i64,
|
||||||
|
mtime: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn op_futime_sync(
|
||||||
|
state: &State,
|
||||||
|
resource_table: &mut ResourceTable,
|
||||||
|
args: Value,
|
||||||
|
_zero_copy: &mut [ZeroCopyBuf],
|
||||||
|
) -> Result<Value, ErrBox> {
|
||||||
|
state.check_unstable("Deno.futimeSync");
|
||||||
|
let args: FutimeArgs = serde_json::from_value(args)?;
|
||||||
|
let rid = args.rid as u32;
|
||||||
|
let atime = filetime::FileTime::from_unix_time(args.atime, 0);
|
||||||
|
let mtime = filetime::FileTime::from_unix_time(args.mtime, 0);
|
||||||
|
|
||||||
|
std_file_resource(resource_table, rid, |r| match r {
|
||||||
|
Ok(std_file) => {
|
||||||
|
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
|
||||||
|
.map_err(ErrBox::from)
|
||||||
|
}
|
||||||
|
Err(_) => Err(ErrBox::type_error(
|
||||||
|
"cannot futime on this type of resource".to_string(),
|
||||||
|
)),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(json!({}))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn op_futime_async(
|
||||||
|
state: Rc<State>,
|
||||||
|
resource_table: Rc<RefCell<ResourceTable>>,
|
||||||
|
args: Value,
|
||||||
|
_zero_copy: BufVec,
|
||||||
|
) -> Result<Value, ErrBox> {
|
||||||
|
state.check_unstable("Deno.futime");
|
||||||
|
let args: FutimeArgs = serde_json::from_value(args)?;
|
||||||
|
let rid = args.rid as u32;
|
||||||
|
let atime = filetime::FileTime::from_unix_time(args.atime, 0);
|
||||||
|
let mtime = filetime::FileTime::from_unix_time(args.mtime, 0);
|
||||||
|
|
||||||
|
let mut resource_table = resource_table.borrow_mut();
|
||||||
|
std_file_resource(&mut resource_table, rid, |r| match r {
|
||||||
|
Ok(std_file) => {
|
||||||
|
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
|
||||||
|
.map_err(ErrBox::from)
|
||||||
|
}
|
||||||
|
Err(_) => Err(ErrBox::type_error(
|
||||||
|
"cannot futime on this type of resource".to_string(),
|
||||||
|
)),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(json!({}))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct UtimeArgs {
|
struct UtimeArgs {
|
||||||
|
|
|
@ -268,6 +268,32 @@
|
||||||
return v instanceof Date ? Math.trunc(v.valueOf() / 1000) : v;
|
return v instanceof Date ? Math.trunc(v.valueOf() / 1000) : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function futimeSync(
|
||||||
|
rid,
|
||||||
|
atime,
|
||||||
|
mtime,
|
||||||
|
) {
|
||||||
|
sendSync("op_futime_sync", {
|
||||||
|
rid,
|
||||||
|
// TODO(caspervonb) split atime, mtime into [seconds, nanoseconds] tuple
|
||||||
|
atime: toSecondsFromEpoch(atime),
|
||||||
|
mtime: toSecondsFromEpoch(mtime),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function futime(
|
||||||
|
rid,
|
||||||
|
atime,
|
||||||
|
mtime,
|
||||||
|
) {
|
||||||
|
await sendAsync("op_futime_async", {
|
||||||
|
rid,
|
||||||
|
// TODO(caspervonb) split atime, mtime into [seconds, nanoseconds] tuple
|
||||||
|
atime: toSecondsFromEpoch(atime),
|
||||||
|
mtime: toSecondsFromEpoch(mtime),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function utimeSync(
|
function utimeSync(
|
||||||
path,
|
path,
|
||||||
atime,
|
atime,
|
||||||
|
@ -364,6 +390,8 @@
|
||||||
umask,
|
umask,
|
||||||
link,
|
link,
|
||||||
linkSync,
|
linkSync,
|
||||||
|
futime,
|
||||||
|
futimeSync,
|
||||||
utime,
|
utime,
|
||||||
utimeSync,
|
utimeSync,
|
||||||
symlink,
|
symlink,
|
||||||
|
|
|
@ -118,6 +118,8 @@ __bootstrap.denoNsUnstable = {
|
||||||
umask: __bootstrap.fs.umask,
|
umask: __bootstrap.fs.umask,
|
||||||
link: __bootstrap.fs.link,
|
link: __bootstrap.fs.link,
|
||||||
linkSync: __bootstrap.fs.linkSync,
|
linkSync: __bootstrap.fs.linkSync,
|
||||||
|
futime: __bootstrap.fs.futime,
|
||||||
|
futimeSync: __bootstrap.fs.futimeSync,
|
||||||
utime: __bootstrap.fs.utime,
|
utime: __bootstrap.fs.utime,
|
||||||
utimeSync: __bootstrap.fs.utimeSync,
|
utimeSync: __bootstrap.fs.utimeSync,
|
||||||
symlink: __bootstrap.fs.symlink,
|
symlink: __bootstrap.fs.symlink,
|
||||||
|
|
|
@ -13,6 +13,50 @@ function assertFuzzyTimestampEquals(t1: Date | null, t2: Date): void {
|
||||||
assert(Math.abs(t1.valueOf() - t2.valueOf()) < 10_000);
|
assert(Math.abs(t1.valueOf() - t2.valueOf()) < 10_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
{ perms: { read: true, write: true } },
|
||||||
|
async function futimeSyncSuccess(): Promise<void> {
|
||||||
|
const testDir = await Deno.makeTempDir();
|
||||||
|
const filename = testDir + "/file.txt";
|
||||||
|
const file = await Deno.open(filename, {
|
||||||
|
create: true,
|
||||||
|
write: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const atime = 1000;
|
||||||
|
const mtime = 50000;
|
||||||
|
await Deno.futime(file.rid, atime, mtime);
|
||||||
|
await Deno.fdatasync(file.rid);
|
||||||
|
|
||||||
|
const fileInfo = Deno.statSync(filename);
|
||||||
|
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
|
||||||
|
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
|
||||||
|
file.close();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
{ perms: { read: true, write: true } },
|
||||||
|
function futimeSyncSuccess(): void {
|
||||||
|
const testDir = Deno.makeTempDirSync();
|
||||||
|
const filename = testDir + "/file.txt";
|
||||||
|
const file = Deno.openSync(filename, {
|
||||||
|
create: true,
|
||||||
|
write: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const atime = 1000;
|
||||||
|
const mtime = 50000;
|
||||||
|
Deno.futimeSync(file.rid, atime, mtime);
|
||||||
|
Deno.fdatasyncSync(file.rid);
|
||||||
|
|
||||||
|
const fileInfo = Deno.statSync(filename);
|
||||||
|
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
|
||||||
|
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
|
||||||
|
file.close();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
unitTest(
|
unitTest(
|
||||||
{ perms: { read: true, write: true } },
|
{ perms: { read: true, write: true } },
|
||||||
function utimeSyncFileSuccess(): void {
|
function utimeSyncFileSuccess(): void {
|
||||||
|
|
|
@ -86,6 +86,8 @@ delete Object.prototype.__proto__;
|
||||||
"fdatasync",
|
"fdatasync",
|
||||||
"fdatasyncSync",
|
"fdatasyncSync",
|
||||||
"formatDiagnostics",
|
"formatDiagnostics",
|
||||||
|
"futime",
|
||||||
|
"futimeSync",
|
||||||
"fstat",
|
"fstat",
|
||||||
"fstatSync",
|
"fstatSync",
|
||||||
"fsync",
|
"fsync",
|
||||||
|
|
Loading…
Reference in a new issue