mirror of
https://github.com/denoland/deno.git
synced 2025-07-24 05:35:33 +00:00
Rename FileInfo time fields and represent them as Date objects (#4932)
This patch also increases the resolution of reported file times to sub-millisecond precision.
This commit is contained in:
parent
c190a0dbc4
commit
ee4e6a1ef9
9 changed files with 143 additions and 130 deletions
10
cli/js/lib.deno.ns.d.ts
vendored
10
cli/js/lib.deno.ns.d.ts
vendored
|
@ -1316,15 +1316,15 @@ declare namespace Deno {
|
|||
/** The last modification time of the file. This corresponds to the `mtime`
|
||||
* field from `stat` on Linux/Mac OS and `ftLastWriteTime` on Windows. This
|
||||
* may not be available on all platforms. */
|
||||
modified: number | null;
|
||||
mtime: Date | null;
|
||||
/** The last access time of the file. This corresponds to the `atime`
|
||||
* field from `stat` on Unix and `ftLastAccessTime` on Windows. This may not
|
||||
* be available on all platforms. */
|
||||
accessed: number | null;
|
||||
atime: Date | null;
|
||||
/** The creation time of the file. This corresponds to the `birthtime`
|
||||
* field from `stat` on Mac/BSD and `ftCreationTime` on Windows. This may not
|
||||
* be available on all platforms. */
|
||||
created: number | null;
|
||||
* field from `stat` on Mac/BSD and `ftCreationTime` on Windows. This may
|
||||
* not be available on all platforms. */
|
||||
birthtime: Date | null;
|
||||
/** ID of the device containing the file.
|
||||
*
|
||||
* _Linux/Mac OS only._ */
|
||||
|
|
|
@ -4,9 +4,9 @@ import { build } from "../../build.ts";
|
|||
|
||||
export interface FileInfo {
|
||||
size: number;
|
||||
modified: number | null;
|
||||
accessed: number | null;
|
||||
created: number | null;
|
||||
mtime: Date | null;
|
||||
atime: Date | null;
|
||||
birthtime: Date | null;
|
||||
dev: number | null;
|
||||
ino: number | null;
|
||||
mode: number | null;
|
||||
|
@ -26,9 +26,9 @@ export interface StatResponse {
|
|||
isDirectory: boolean;
|
||||
isSymlink: boolean;
|
||||
size: number;
|
||||
modified: number;
|
||||
accessed: number;
|
||||
created: number;
|
||||
mtime: number | null;
|
||||
atime: number | null;
|
||||
birthtime: number | null;
|
||||
// Null for stat(), but exists for readdir().
|
||||
name: string | null;
|
||||
// Unix only members
|
||||
|
@ -51,9 +51,9 @@ export function parseFileInfo(response: StatResponse): FileInfo {
|
|||
isDirectory: response.isDirectory,
|
||||
isSymlink: response.isSymlink,
|
||||
size: response.size,
|
||||
modified: response.modified ? response.modified : null,
|
||||
accessed: response.accessed ? response.accessed : null,
|
||||
created: response.created ? response.created : null,
|
||||
mtime: response.mtime != null ? new Date(response.mtime) : null,
|
||||
atime: response.atime != null ? new Date(response.atime) : null,
|
||||
birthtime: response.birthtime != null ? new Date(response.birthtime) : null,
|
||||
// Only non-null if on Unix
|
||||
dev: isUnix ? response.dev : null,
|
||||
ino: isUnix ? response.ino : null,
|
||||
|
|
|
@ -1,21 +1,31 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assert, assertEquals } from "./test_util.ts";
|
||||
|
||||
// TODO Add tests for modified, accessed, and created fields once there is a way
|
||||
// to create temp files.
|
||||
unitTest({ perms: { read: true } }, function statSyncSuccess(): void {
|
||||
const packageInfo = Deno.statSync("README.md");
|
||||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
function statSyncSuccess(): void {
|
||||
const packageInfo = Deno.statSync("README.md");
|
||||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
|
||||
const modulesInfo = Deno.statSync("cli/tests/symlink_to_subdir");
|
||||
assert(modulesInfo.isDirectory);
|
||||
assert(!modulesInfo.isSymlink);
|
||||
const modulesInfo = Deno.statSync("cli/tests/symlink_to_subdir");
|
||||
assert(modulesInfo.isDirectory);
|
||||
assert(!modulesInfo.isSymlink);
|
||||
|
||||
const testsInfo = Deno.statSync("cli/tests");
|
||||
assert(testsInfo.isDirectory);
|
||||
assert(!testsInfo.isSymlink);
|
||||
});
|
||||
const testsInfo = Deno.statSync("cli/tests");
|
||||
assert(testsInfo.isDirectory);
|
||||
assert(!testsInfo.isSymlink);
|
||||
|
||||
const tempFile = Deno.makeTempFileSync();
|
||||
const tempInfo = Deno.statSync(tempFile);
|
||||
const now = Date.now();
|
||||
assert(tempInfo.atime !== null && now - tempInfo.atime.valueOf() < 1000);
|
||||
assert(tempInfo.mtime !== null && now - tempInfo.mtime.valueOf() < 1000);
|
||||
assert(
|
||||
tempInfo.birthtime === null || now - tempInfo.birthtime.valueOf() < 1000
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
unitTest({ perms: { read: false } }, function statSyncPerm(): void {
|
||||
let caughtError = false;
|
||||
|
@ -83,21 +93,32 @@ unitTest({ perms: { read: true } }, function lstatSyncNotFound(): void {
|
|||
assertEquals(badInfo, undefined);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, async function statSuccess(): Promise<
|
||||
void
|
||||
> {
|
||||
const packageInfo = await Deno.stat("README.md");
|
||||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function statSuccess(): Promise<void> {
|
||||
const packageInfo = await Deno.stat("README.md");
|
||||
assert(packageInfo.isFile);
|
||||
assert(!packageInfo.isSymlink);
|
||||
|
||||
const modulesInfo = await Deno.stat("cli/tests/symlink_to_subdir");
|
||||
assert(modulesInfo.isDirectory);
|
||||
assert(!modulesInfo.isSymlink);
|
||||
const modulesInfo = await Deno.stat("cli/tests/symlink_to_subdir");
|
||||
assert(modulesInfo.isDirectory);
|
||||
assert(!modulesInfo.isSymlink);
|
||||
|
||||
const testsInfo = await Deno.stat("cli/tests");
|
||||
assert(testsInfo.isDirectory);
|
||||
assert(!testsInfo.isSymlink);
|
||||
});
|
||||
const testsInfo = await Deno.stat("cli/tests");
|
||||
assert(testsInfo.isDirectory);
|
||||
assert(!testsInfo.isSymlink);
|
||||
|
||||
const tempFile = await Deno.makeTempFile();
|
||||
const tempInfo = await Deno.stat(tempFile);
|
||||
const now = Date.now();
|
||||
assert(tempInfo.atime !== null && now - tempInfo.atime.valueOf() < 1000);
|
||||
assert(tempInfo.mtime !== null && now - tempInfo.mtime.valueOf() < 1000);
|
||||
|
||||
assert(
|
||||
tempInfo.birthtime === null || now - tempInfo.birthtime.valueOf() < 1000
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
unitTest({ perms: { read: false } }, async function statPerm(): Promise<void> {
|
||||
let caughtError = false;
|
||||
|
|
|
@ -4,9 +4,9 @@ import { unitTest, assert } from "./test_util.ts";
|
|||
// Allow 10 second difference.
|
||||
// Note this might not be enough for FAT (but we are not testing on such fs).
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function assertFuzzyTimestampEquals(t1: any, t2: number): void {
|
||||
assert(typeof t1 === "number");
|
||||
assert(Math.abs(t1 - t2) < 10);
|
||||
function assertFuzzyTimestampEquals(t1: Date | null, t2: Date): void {
|
||||
assert(t1 instanceof Date);
|
||||
assert(Math.abs(t1.valueOf() - t2.valueOf()) < 10_000);
|
||||
}
|
||||
|
||||
unitTest(
|
||||
|
@ -23,8 +23,8 @@ unitTest(
|
|||
Deno.utimeSync(filename, atime, mtime);
|
||||
|
||||
const fileInfo = Deno.statSync(filename);
|
||||
assertFuzzyTimestampEquals(fileInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(fileInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
|
||||
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -38,8 +38,8 @@ unitTest(
|
|||
Deno.utimeSync(testDir, atime, mtime);
|
||||
|
||||
const dirInfo = Deno.statSync(testDir);
|
||||
assertFuzzyTimestampEquals(dirInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(dirInfo.atime, new Date(atime * 1000));
|
||||
assertFuzzyTimestampEquals(dirInfo.mtime, new Date(mtime * 1000));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -48,13 +48,13 @@ unitTest(
|
|||
function utimeSyncDateSuccess(): void {
|
||||
const testDir = Deno.makeTempDirSync();
|
||||
|
||||
const atime = 1000;
|
||||
const mtime = 50000;
|
||||
Deno.utimeSync(testDir, new Date(atime * 1000), new Date(mtime * 1000));
|
||||
const atime = new Date(1000_000);
|
||||
const mtime = new Date(50000_000);
|
||||
Deno.utimeSync(testDir, atime, mtime);
|
||||
|
||||
const dirInfo = Deno.statSync(testDir);
|
||||
assertFuzzyTimestampEquals(dirInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(dirInfo.atime, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.mtime, mtime);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -71,15 +71,8 @@ unitTest(
|
|||
Deno.utimeSync(filename, atime, mtime);
|
||||
|
||||
const fileInfo = Deno.statSync(filename);
|
||||
// atime and mtime must be scaled by a factor of 1000 to be recorded in seconds
|
||||
assertFuzzyTimestampEquals(
|
||||
fileInfo.accessed,
|
||||
Math.trunc(atime.valueOf() / 1000)
|
||||
);
|
||||
assertFuzzyTimestampEquals(
|
||||
fileInfo.modified,
|
||||
Math.trunc(mtime.valueOf() / 1000)
|
||||
);
|
||||
assertFuzzyTimestampEquals(fileInfo.atime, atime);
|
||||
assertFuzzyTimestampEquals(fileInfo.mtime, mtime);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -95,8 +88,8 @@ unitTest(
|
|||
Deno.utimeSync(testDir, atime, mtime);
|
||||
|
||||
const dirInfo = Deno.statSync(testDir);
|
||||
assertFuzzyTimestampEquals(dirInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(dirInfo.atime, new Date(atime * 1000));
|
||||
assertFuzzyTimestampEquals(dirInfo.mtime, new Date(mtime * 1000));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -148,8 +141,8 @@ unitTest(
|
|||
await Deno.utime(filename, atime, mtime);
|
||||
|
||||
const fileInfo = Deno.statSync(filename);
|
||||
assertFuzzyTimestampEquals(fileInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(fileInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
|
||||
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -163,8 +156,8 @@ unitTest(
|
|||
await Deno.utime(testDir, atime, mtime);
|
||||
|
||||
const dirInfo = Deno.statSync(testDir);
|
||||
assertFuzzyTimestampEquals(dirInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(dirInfo.atime, new Date(atime * 1000));
|
||||
assertFuzzyTimestampEquals(dirInfo.mtime, new Date(mtime * 1000));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -173,13 +166,13 @@ unitTest(
|
|||
async function utimeDateSuccess(): Promise<void> {
|
||||
const testDir = Deno.makeTempDirSync();
|
||||
|
||||
const atime = 1000;
|
||||
const mtime = 50000;
|
||||
await Deno.utime(testDir, new Date(atime * 1000), new Date(mtime * 1000));
|
||||
const atime = new Date(100_000);
|
||||
const mtime = new Date(5000_000);
|
||||
await Deno.utime(testDir, atime, mtime);
|
||||
|
||||
const dirInfo = Deno.statSync(testDir);
|
||||
assertFuzzyTimestampEquals(dirInfo.accessed, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.modified, mtime);
|
||||
assertFuzzyTimestampEquals(dirInfo.atime, atime);
|
||||
assertFuzzyTimestampEquals(dirInfo.mtime, mtime);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -197,15 +190,8 @@ unitTest(
|
|||
await Deno.utime(filename, atime, mtime);
|
||||
|
||||
const fileInfo = Deno.statSync(filename);
|
||||
// The dates must be scaled by a factored of 1000 to make them seconds
|
||||
assertFuzzyTimestampEquals(
|
||||
fileInfo.accessed,
|
||||
Math.trunc(atime.valueOf() / 1000)
|
||||
);
|
||||
assertFuzzyTimestampEquals(
|
||||
fileInfo.modified,
|
||||
Math.trunc(mtime.valueOf() / 1000)
|
||||
);
|
||||
assertFuzzyTimestampEquals(fileInfo.atime, atime);
|
||||
assertFuzzyTimestampEquals(fileInfo.mtime, mtime);
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue