node icon indicating copy to clipboard operation
node copied to clipboard

Stabilize `fs.cp()`, `fs.cpSync()`, `fsPromises.cp()` methods

Open theoludwig opened this issue 2 years ago • 8 comments

What is the problem this feature will solve?

Currently, these methods are marked as Experimental (Stability: 1):

There were no major changes since their introduction in Node.js v16.7.0, so it should be safe to mark them Stable (Stability: 2) as per the Stability index.

If somehow, these methods are still not ready to be stable, this is a tracking issue/roadmap to know what are the needed TODOs before marking them as stable.

What is the feature you are proposing to solve the problem?

Marking fs.cp(), fs.cpSync(), fsPromises.cp() methods as stable (Stability: 2).

For automated test purposes, mocking fs module is a must. Currently, the most used userland library for that is probably mock-fs, and doesn't support these methods. Before marking this API stable, Node.js should provide the needed feature(s) for mocking this API in userland, or even better, include mock-fs in Node.js core, this can be well suited with the new test_runner module.

Related issues: https://github.com/tschaub/mock-fs/issues/358, https://github.com/nodejs/node/issues/37746.

What alternatives have you considered?

I think it's best to avoid using experimental APIs, avoid warnings, and simply use features subject to semantic-versioning for easier Node.js upgrades.

The current workaround, I personally use and end up copy/pasting in several projects (too small to be an npm package IMO):

import fs from 'node:fs'
import path from 'node:path'

export const copyDirectory = async (
  source: string,
  destination: string
): Promise<void> => {
  const filesToCreate = await fs.promises.readdir(source)
  for (const file of filesToCreate) {
    const originalFilePath = path.join(source, file)
    const stats = await fs.promises.stat(originalFilePath)
    if (stats.isFile()) {
      const writePath = path.join(destination, file)
      await fs.promises.copyFile(originalFilePath, writePath)
    } else if (stats.isDirectory()) {
      await fs.promises.mkdir(path.join(destination, file))
      await copyDirectory(path.join(source, file), path.join(destination, file))
    }
  }
}

By marking this API as stable, I should be able to use it like this:

import fs from 'node:fs'

await fs.promises.cp(source, destination, { recursive: true })

theoludwig avatar Sep 11 '22 12:09 theoludwig