Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[node] bigint options for fstat and lstat #50120

Merged
merged 4 commits into from Feb 19, 2021
Merged

[node] bigint options for fstat and lstat #50120

merged 4 commits into from Feb 19, 2021

Conversation

xandris
Copy link
Contributor

@xandris xandris commented Dec 14, 2020

According to the Node Filesystem API, these methods all support an opts parameter that allows it to return bigint stats:

  • stat
  • lstat
  • fstat

They support the bigint option in the following modes:

  • Callback
  • Synchronous
  • util.promisify
  • fs.promises

Each call signature can handle these arguments:

  • No extra argument yields Stats
  • Passing undefined yields Stats
  • Passing an empty object yields Stats
  • Passing { bigint: false } yields Stats
  • Passing { bigint: true } yields BigIntStats

The work was already done for stat and statSync, so this PR just extends that to lstat and fstat async and sync variants and makes the call signatures a bit more liberal.

I switched the call signatures from using the BigIntOptions type to using types like StatOptions & { bigint: true } where needed. This is the approach already taken by mkdir to handle the recursive option, for example. Also, it's acceptable to pass in an empty options object, so I made StatOptions.bigint optional.

fs.promises.fstat doesn't appear to have ever existed. (I looked at all the Node JS API documents going back to version 10.) This PR removes it. This functionality is implemented by FileHandle.stat.

These definitions go back to Node 10, but the v10 and v11 variants didn't have the other definitions for bigint stats, so I didn't touch those.

Please fill in this template.

Select one of these and delete the others:

If changing an existing definition:

@typescript-bot typescript-bot added Critical package Untested Change This PR does not touch tests labels Dec 14, 2020
@typescript-bot typescript-bot added this to Waiting for Code Reviews in New Pull Request Status Board Dec 14, 2020
@typescript-bot
Copy link
Contributor

typescript-bot commented Dec 14, 2020

@xandris Thank you for submitting this PR!

This is a live comment which I will keep updated.

1 package in this PR

Code Reviews

Because this is a widely-used package, a DT maintainer will need to review it before it can be merged.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • ✅ Most recent commit is approved by a DT maintainer

All of the items on the list are green. To merge, you need to post a comment including the string "Ready to merge" to bring in your changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 50120,
  "author": "xandris",
  "headCommitOid": "1e39b21b87ab4fe6bc6d43739fa5cbcde9f801ec",
  "lastPushDate": "2021-02-03T06:23:08.000Z",
  "lastActivityDate": "2021-02-19T00:03:57.000Z",
  "maintainerBlessed": false,
  "mergeOfferDate": "2021-02-18T16:28:25.000Z",
  "mergeRequestDate": "2021-02-19T00:03:57.000Z",
  "mergeRequestUser": "xandris",
  "hasMergeConflict": false,
  "isFirstContribution": false,
  "popularityLevel": "Critical",
  "pkgInfo": [
    {
      "name": "node",
      "kind": "edit",
      "files": [
        {
          "path": "types/node/fs.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/fs/promises.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/test/fs.ts",
          "kind": "test"
        },
        {
          "path": "types/node/v12/fs.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/v13/fs.d.ts",
          "kind": "definition"
        }
      ],
      "owners": [
        "Microsoft",
        "DefinitelyTyped",
        "jkomyno",
        "a-tarasyuk",
        "alvis",
        "r3nya",
        "btoueg",
        "brunoscheufler",
        "smac89",
        "touffy",
        "DeividasBakanas",
        "eyqs",
        "Hannes-Magnusson-CK",
        "KSXGitHub",
        "hoo29",
        "kjin",
        "ajafff",
        "islishude",
        "mwiktorczyk",
        "mohsen1",
        "n-e",
        "galkin",
        "parambirs",
        "eps1lon",
        "SimonSchick",
        "ThomasdenH",
        "WilcoBakker",
        "wwwy3y3",
        "samuela",
        "kuehlein",
        "j-oliveras",
        "bhongy",
        "chyzwar",
        "trivikr",
        "nguymin4",
        "yoursunny",
        "qwelias",
        "ExE-Boss",
        "Ryan-Willpower",
        "peterblazejewicz",
        "addaleax",
        "JasonHK",
        "victorperin",
        "ZYSzys"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    }
  ],
  "reviews": [
    {
      "type": "approved",
      "reviewer": "orta",
      "date": "2021-02-18T16:27:45.000Z",
      "isMaintainer": true
    }
  ],
  "ciResult": "pass"
}

@typescript-bot typescript-bot added the The CI failed When GH Actions fails label Dec 14, 2020
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Author Action in New Pull Request Status Board Dec 14, 2020
@typescript-bot
Copy link
Contributor

@xandris The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot
Copy link
Contributor

👋 Hi there! I’ve run some quick measurements against master and your PR. These metrics should help the humans reviewing this PR gauge whether it might negatively affect compile times or editor responsiveness for users who install these typings.

Let’s review the numbers, shall we?

node/v14.14

Comparison details for node/14.14 📊
master #50120 diff
Batch compilation
Memory usage (MiB) 110.9 108.2 -2.4%
Type count 17683 17687 0%
Assignability cache size 5062 5062 0%
Language service
Samples taken 28 28 0%
Identifiers in tests 28 28 0%
getCompletionsAtPosition
    Mean duration (ms) 648.8 646.2 -0.4%
    Mean CV 10.2% 11.3%
    Worst duration (ms) 754.7 760.9 +0.8%
    Worst identifier preopens preopens
getQuickInfoAtPosition
    Mean duration (ms) 643.8 633.7 -1.6%
    Mean CV 10.3% 9.6%
    Worst duration (ms) 703.9 695.9 -1.1%
    Worst identifier wasm WebAssembly

It looks like nothing changed too much. I won’t post performance data again unless it gets worse.

node/v14.14

Comparison details for node/14.14 📊
master #50120 diff
Batch compilation
Memory usage (MiB) 103.3 107.9 +4.5%
Type count 17683 17687 0%
Assignability cache size 5062 5062 0%
Language service
Samples taken 28 28 0%
Identifiers in tests 28 28 0%
getCompletionsAtPosition
    Mean duration (ms) 643.1 646.2 +0.5%
    Mean CV 10.8% 8.4%
    Worst duration (ms) 737.5 787.9 +6.8%
    Worst identifier wasm preopens
getQuickInfoAtPosition
    Mean duration (ms) 635.0 617.0 -2.8%
    Mean CV 10.5% 8.9%
    Worst duration (ms) 731.9 697.6 -4.7%
    Worst identifier preopens preopens

It looks like nothing changed too much. I won’t post performance data again unless it gets worse.

node/v14.14

Comparison details for node/14.14 📊
master #50120 diff
Batch compilation
Memory usage (MiB) 113.9 109.1 -4.2%
Type count 17683 17687 0%
Assignability cache size 5062 5062 0%
Language service
Samples taken 28 28 0%
Identifiers in tests 28 28 0%
getCompletionsAtPosition
    Mean duration (ms) 642.9 636.1 -1.1%
    Mean CV 10.6% 9.9%
    Worst duration (ms) 723.3 742.5 +2.6%
    Worst identifier wasi instance
getQuickInfoAtPosition
    Mean duration (ms) 636.2 635.9 -0.1%
    Mean CV 9.5% 9.8%
    Worst duration (ms) 708.0 713.2 +0.7%
    Worst identifier returnOnExit importObject

It looks like nothing changed too much. I won’t post performance data again unless it gets worse.

@typescript-bot typescript-bot added the Perf: Same typescript-bot determined that this PR will not significantly impact compilation performance. label Dec 14, 2020
@xandris
Copy link
Contributor Author

xandris commented Dec 15, 2020

Half baked, closing for now

@xandris xandris closed this Dec 15, 2020
@typescript-bot typescript-bot removed this from Needs Author Action in New Pull Request Status Board Dec 15, 2020
@xandris xandris reopened this Dec 15, 2020
@typescript-bot typescript-bot removed The CI failed When GH Actions fails Untested Change This PR does not touch tests labels Dec 15, 2020
@typescript-bot typescript-bot added this to Waiting for Code Reviews in New Pull Request Status Board Dec 15, 2020
@typescript-bot typescript-bot added the The CI failed When GH Actions fails label Dec 15, 2020
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Author Action in New Pull Request Status Board Dec 15, 2020
@typescript-bot
Copy link
Contributor

@xandris The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@xandris
Copy link
Contributor Author

xandris commented Dec 15, 2020 via email

@xandris
Copy link
Contributor Author

xandris commented Dec 15, 2020

Okay, last tweak incoming. The inference should support these cases:

  • If you know the options are defined and bigint is true, then you'll always get BigIntStats
  • If the options might be defined, but would have bigint undefined or false, then you'll always get Stats
  • If the options might be defined, but you don't know anything about them, you can get either Stats or BigIntStats
  • If the options are undefined, you'll always get Stats.

Based on this playground I think I need 3 overloads for opts in the final position, and a fourth for the callback case where the opts in the middle of the parameter list. So, almost there, just need to make the bigint: false case with an optional param and put the false case first. I think I was imagining some case where TypeScript would automatically deduce the general case from the false and true cases, but it's probably a good thing it doesn't!

@typescript-bot typescript-bot removed the The CI failed When GH Actions fails label Dec 15, 2020
@typescript-bot typescript-bot moved this from Needs Author Action to Waiting for Code Reviews in New Pull Request Status Board Dec 15, 2020
@typescript-bot typescript-bot added the The CI failed When GH Actions fails label Dec 15, 2020
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Author Action in New Pull Request Status Board Dec 15, 2020
@typescript-bot
Copy link
Contributor

@xandris The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot typescript-bot added Where is GH Actions? GH Actions didn't give a response to this PR Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. labels Jan 4, 2021
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Author Action in New Pull Request Status Board Feb 3, 2021
@typescript-bot
Copy link
Contributor

@xandris The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot typescript-bot removed the The CI failed When GH Actions fails label Feb 3, 2021
@typescript-bot typescript-bot moved this from Needs Author Action to Needs Maintainer Review in New Pull Request Status Board Feb 3, 2021
export function stat(path: PathLike, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
export function stat(path: PathLike, options: StatOptions & { bigint?: false } | undefined, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
export function stat(path: PathLike, options: StatOptions & { bigint: true }, callback: (err: NodeJS.ErrnoException | null, stats: BigIntStats) => void): void;
export function stat(path: PathLike, options: StatOptions | undefined, callback: (err: NodeJS.ErrnoException | null, stats: Stats | BigIntStats) => void): void;
Copy link
Contributor

@Flarna Flarna Feb 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the options === undefined case is not optimal here as the result should be of type Stats.

I think omitting | undefined here is better because this case is handled correct by the overload two lines above.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its possible you could have a weakly defined StatOptions | undefined that you want to pass in, which should be legal. Since you can't differentiate between whether its a Stats or BigIntStats due to the weaker type, I would expect that to be the result. This definition looks fine to me.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the undefined case should hit the first overload (with & { bigint?: false }), which will correctly return Stats.

export function stat(path: PathLike, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
export function stat(path: PathLike, options: StatOptions & { bigint?: false } | undefined, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
export function stat(path: PathLike, options: StatOptions & { bigint: true }, callback: (err: NodeJS.ErrnoException | null, stats: BigIntStats) => void): void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the advantage of StatOptions & { bigint: true } compared to BigIntOptions used till now?

Copy link
Collaborator

@rbuckton rbuckton Feb 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually looks easier to see why this matters with the options inline.

export function stat(path: PathLike, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
export function stat(path: PathLike, options: StatOptions & { bigint?: false } | undefined, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is quite some copy paste of this compound type.
What about adding something like this instead:

interface NoBigIntOptions {
  bigint?: false;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually looks easier to see why this matters with the options inline. Are you recommending it be StatOptions & NoBigIntOptions? Or are you recommending a NoBigIntOptions interface that inherits from StatOptions? If the latter, The naming of BigIntOptions/NoBigIntOptions seems very ambiguous to me. Personally, I'd rather see either:

  1. StatOptions & { bigint: true } (as is written), or
  2. BigIntStatOptions/NoBigIntStatOptions (indicating the specific variations of StatOptions

Personally I think (1) is easier to read and reason over.


// NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime.
export namespace stat {
/**
* Asynchronous stat(2) - Get file status.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
*/
function __promisify__(path: PathLike, options: BigIntOptions): Promise<BigIntStats>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should BigIntOptions be deprecated since it's not referenced in the API anymore?

@rbuckton
Copy link
Collaborator

@Flarna do you have any other comments or feedback on this one? If not, I'll go ahead and approve.

@typescript-bot typescript-bot added the Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. label Feb 14, 2021
@typescript-bot
Copy link
Contributor

typescript-bot commented Feb 14, 2021

@Flarna
Copy link
Contributor

Flarna commented Feb 14, 2021

@Flarna do you have any other comments or feedback on this one? If not, I'll go ahead and approve.

@rbuckton No more comments.

Copy link
Collaborator

@orta orta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Giving Ron's approval, as this looks right to me after a read through of the discussion

@typescript-bot typescript-bot added Maintainer Approved Self Merge This PR can now be self-merged by the PR author or an owner and removed Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. labels Feb 18, 2021
@typescript-bot typescript-bot moved this from Needs Maintainer Review to Waiting for Author to Merge in New Pull Request Status Board Feb 18, 2021
@typescript-bot
Copy link
Contributor

@xandris Everything looks good here. Great job! I am ready to merge this PR (at 1e39b21) on your behalf.

If you'd like that to happen, please post a comment saying:

Ready to merge

and I'll merge this PR almost instantly. Thanks for helping out! ❤️

(@microsoft, @DefinitelyTyped, @jkomyno, @a-tarasyuk, @alvis, @r3nya, @btoueg, @BrunoScheufler, @smac89, @Touffy, @DeividasBakanas, @eyqs, @Hannes-Magnusson-CK, @KSXGitHub, @hoo29, @kjin, @ajafff, @islishude, @mwiktorczyk, @mohsen1, @n-e, @galkin, @parambirs, @eps1lon, @SimonSchick, @ThomasdenH, @WilcoBakker, @wwwy3y3, @samuela, @kuehlein, @j-oliveras, @bhongy, @chyzwar, @trivikr, @nguymin4, @yoursunny, @qwelias, @ExE-Boss, @Ryan-Willpower, @peterblazejewicz, @addaleax, @JasonHK, @victorperin, @ZYSzys: you can do this too.)

@xandris
Copy link
Contributor Author

xandris commented Feb 19, 2021

Ready to merge

@typescript-bot typescript-bot moved this from Waiting for Author to Merge to Recently Merged in New Pull Request Status Board Feb 19, 2021
@typescript-bot typescript-bot merged commit 5967146 into DefinitelyTyped:master Feb 19, 2021
@typescript-bot
Copy link
Contributor

I just published @types/node@14.14.30 to npm.

@typescript-bot
Copy link
Contributor

I just published @types/node@13.13.44 to npm.

@typescript-bot
Copy link
Contributor

I just published @types/node@12.20.3 to npm.

@typescript-bot typescript-bot removed this from Recently Merged in New Pull Request Status Board Feb 19, 2021
ansu5555 pushed a commit to ansu5555/DefinitelyTyped that referenced this pull request Feb 19, 2021
…lstat by @xandris

* [node] bigint options for fstat and lstat

* [node] fixes for stat, fstat, lstat in all modes

Changes the overloads to be more in line with the mkdir recursive API by
consistently using StatOptions, making the bigint field optional, and
using { bigint: true } and { bigint?: false } cases to discriminate
between Stats and BigIntStats where possible.

Also fs.promises.fstat doesn't seem to have ever existed.

* [node] more stat/lstat/fstat overload tweaks, more tests

* node: fix some copypasta in v12
kaznovac pushed a commit to kaznovac/DefinitelyTyped that referenced this pull request Mar 2, 2021
…lstat by @xandris

* [node] bigint options for fstat and lstat

* [node] fixes for stat, fstat, lstat in all modes

Changes the overloads to be more in line with the mkdir recursive API by
consistently using StatOptions, making the bigint field optional, and
using { bigint: true } and { bigint?: false } cases to discriminate
between Stats and BigIntStats where possible.

Also fs.promises.fstat doesn't seem to have ever existed.

* [node] more stat/lstat/fstat overload tweaks, more tests

* node: fix some copypasta in v12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Critical package Maintainer Approved Perf: Same typescript-bot determined that this PR will not significantly impact compilation performance. Self Merge This PR can now be self-merged by the PR author or an owner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants