Skip to content

Commit

Permalink
feat(fslib): add rmPromise/rmSync methods (#6226)
Browse files Browse the repository at this point in the history
**What's the problem this PR addresses?**
<!-- Describe the rationale of your PR. -->
<!-- Link all issues that it closes. (Closes/Resolves #xxxx.) -->

The `recursive` option of `rmdir` is deprecated in Node.js.
Unfortunately, because this lib doesn't expose the `rm` method, there's
no alternative atm. This PR adds that alternative.

https://nodejs.org/api/deprecations.html#DEP0147

...

**How did you fix it?**
<!-- A detailed description of your implementation. -->

I copied the `rmdir` implementations into a `rm` equivalent methods that
calls in the `fs.rm` instead of `fs.rmdir`.
...

**Checklist**
<!--- Don't worry if you miss something, chores are automatically
tested. -->
<!--- This checklist exists to help you remember doing the chores when
you submit a PR. -->
<!--- Put an `x` in all the boxes that apply. -->
- [x] I have read the [Contributing
Guide](https://yarnpkg.com/advanced/contributing).

<!-- See
https://yarnpkg.com/advanced/contributing#preparing-your-pr-to-be-released
for more details. -->
<!-- Check with `yarn version check` and fix with `yarn version check
-i` -->
- [x] I have set the packages that need to be released for my changes to
be effective.

<!-- The "Testing chores" workflow validates that your PR follows our
guidelines. -->
<!-- If it doesn't pass, click on it to see details as to what your PR
might be missing. -->
- [x] I will check that all automated PR checks pass before the PR gets
reviewed.

---------

Co-authored-by: Maël Nison <nison.mael@gmail.com>
  • Loading branch information
aduh95 and arcanis committed May 6, 2024
1 parent ebf9a0d commit 7627325
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 7 deletions.
36 changes: 36 additions & 0 deletions .yarn/versions/5b3411ac.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
releases:
"@yarnpkg/fslib": minor
"@yarnpkg/libzip": minor
"@yarnpkg/pnpify": minor

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-exec"
- "@yarnpkg/plugin-file"
- "@yarnpkg/plugin-git"
- "@yarnpkg/plugin-github"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-link"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- vscode-zipfs
- "@yarnpkg/builder"
- "@yarnpkg/cli"
- "@yarnpkg/core"
- "@yarnpkg/doctor"
- "@yarnpkg/nm"
- "@yarnpkg/pnp"
- "@yarnpkg/sdks"
- "@yarnpkg/shell"
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,5 @@
"micromatch": "^4.0.2",
"semver": "^7.1.2"
},
"packageManager": "yarn@4.1.1+sha256.f3cc0eda8e5560e529c7147565b30faa43b4e472d90e8634d7134a37c7f59781"
"packageManager": "yarn@4.2.1+sha256.15ce76682a8cd2090257b883cd69c637925b29573f9573e8403ec227d5ab6815"
}
11 changes: 11 additions & 0 deletions packages/yarnpkg-fslib/sources/FakeFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,16 @@ export type MkdirOptions = Partial<{

export type RmdirOptions = Partial<{
maxRetries: number;
retryDelay: number;
/** @deprecated Use `rm` instead of `rmdir` */
recursive: boolean;
}>;

export type RmOptions = Partial<{
maxRetries: number;
retryDelay: number;
force: boolean;
recursive: boolean;
}>;

export type WriteFileOptions = Partial<{
Expand Down Expand Up @@ -255,6 +263,9 @@ export abstract class FakeFS<P extends Path> {
abstract rmdirPromise(p: P, opts?: RmdirOptions): Promise<void>;
abstract rmdirSync(p: P, opts?: RmdirOptions): void;

abstract rmPromise(p: P, opts?: RmOptions): Promise<void>;
abstract rmSync(p: P, opts?: RmOptions): void;

abstract linkPromise(existingP: P, newP: P): Promise<void>;
abstract linkSync(existingP: P, newP: P): void;

Expand Down
18 changes: 17 additions & 1 deletion packages/yarnpkg-fslib/sources/MountFS.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {BigIntStats, constants, Stats} from 'fs';

import {WatchOptions, WatchCallback, Watcher, StatOptions, StatSyncOptions, ReaddirOptions, DirentNoPath} from './FakeFS';
import {WatchOptions, WatchCallback, Watcher, StatOptions, StatSyncOptions, ReaddirOptions, DirentNoPath, RmOptions} from './FakeFS';
import {FakeFS, MkdirOptions, RmdirOptions, WriteFileOptions, OpendirOptions} from './FakeFS';
import {Dirent, SymlinkType} from './FakeFS';
import {CreateReadStreamOptions, CreateWriteStreamOptions, BasePortableFakeFS, ExtractHintOptions, WatchFileOptions, WatchFileCallback, StatWatcher} from './FakeFS';
Expand Down Expand Up @@ -752,6 +752,22 @@ export class MountFS<MountedFS extends MountableFS> extends BasePortableFakeFS {
});
}


async rmPromise(p: PortablePath, opts?: RmOptions) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.rmPromise(p, opts);
}, async (mountFs, {subPath}) => {
return await mountFs.rmPromise(subPath, opts);
});
}

rmSync(p: PortablePath, opts?: RmOptions) {
return this.makeCallSync(p, () => {
return this.baseFs.rmSync(p, opts);
}, (mountFs, {subPath}) => {
return mountFs.rmSync(subPath, opts);
});
}
async linkPromise(existingP: PortablePath, newP: PortablePath) {
return await this.makeCallPromise(newP, async () => {
return await this.baseFs.linkPromise(existingP, newP);
Expand Down
8 changes: 8 additions & 0 deletions packages/yarnpkg-fslib/sources/NoFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ export class NoFS extends FakeFS<PortablePath> {
throw makeError();
}

async rmPromise(): Promise<never> {
throw makeError();
}

rmSync(): never {
throw makeError();
}

async linkPromise(): Promise<never> {
throw makeError();
}
Expand Down
17 changes: 16 additions & 1 deletion packages/yarnpkg-fslib/sources/NodeFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fs, {BigIntStats, Stats}
import {CreateReadStreamOptions, CreateWriteStreamOptions, Dir, StatWatcher, WatchFileCallback, WatchFileOptions, OpendirOptions, ReaddirOptions, DirentNoPath} from './FakeFS';
import {Dirent, SymlinkType, StatSyncOptions, StatOptions} from './FakeFS';
import {BasePortableFakeFS, WriteFileOptions} from './FakeFS';
import {MkdirOptions, RmdirOptions, WatchOptions, WatchCallback, Watcher} from './FakeFS';
import {MkdirOptions, RmdirOptions, RmOptions, WatchOptions, WatchCallback, Watcher} from './FakeFS';
import {FSPath, PortablePath, Filename, ppath, npath, NativePath} from './path';

function direntToPortable(dirent: Dirent<NativePath>): Dirent<PortablePath> {
Expand Down Expand Up @@ -428,6 +428,21 @@ export class NodeFS extends BasePortableFakeFS {
return this.realFs.rmdirSync(npath.fromPortablePath(p), opts);
}

async rmPromise(p: PortablePath, opts?: RmOptions) {
return await new Promise<void>((resolve, reject) => {
// TODO: always pass opts when min node version is 12.10+
if (opts) {
this.realFs.rm(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject));
} else {
this.realFs.rm(npath.fromPortablePath(p), this.makeCallback(resolve, reject));
}
});
}

rmSync(p: PortablePath, opts?: RmOptions) {
return this.realFs.rmSync(npath.fromPortablePath(p), opts);
}

async linkPromise(existingP: PortablePath, newP: PortablePath) {
return await new Promise<void>((resolve, reject) => {
this.realFs.link(npath.fromPortablePath(existingP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject));
Expand Down
10 changes: 9 additions & 1 deletion packages/yarnpkg-fslib/sources/ProxiedFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Stats, BigIntStats}

import {CreateReadStreamOptions, CreateWriteStreamOptions, FakeFS, ExtractHintOptions, WatchFileCallback, WatchFileOptions, StatWatcher, Dir, OpendirOptions, ReaddirOptions, DirentNoPath} from './FakeFS';
import {Dirent, SymlinkType, StatSyncOptions, StatOptions} from './FakeFS';
import {MkdirOptions, RmdirOptions, WriteFileOptions, WatchCallback, WatchOptions, Watcher} from './FakeFS';
import {MkdirOptions, RmdirOptions, RmOptions, WriteFileOptions, WatchCallback, WatchOptions, Watcher} from './FakeFS';
import {FSPath, Filename, Path} from './path';

export abstract class ProxiedFS<P extends Path, IP extends Path> extends FakeFS<P> {
Expand Down Expand Up @@ -270,6 +270,14 @@ export abstract class ProxiedFS<P extends Path, IP extends Path> extends FakeFS<
return this.baseFs.rmdirSync(this.mapToBase(p), opts);
}

async rmPromise(p: P, opts?: RmOptions) {
return this.baseFs.rmPromise(this.mapToBase(p), opts);
}

rmSync(p: P, opts?: RmOptions) {
return this.baseFs.rmSync(this.mapToBase(p), opts);
}

async linkPromise(existingP: P, newP: P) {
return this.baseFs.linkPromise(this.mapToBase(existingP), this.mapToBase(newP));
}
Expand Down
2 changes: 1 addition & 1 deletion packages/yarnpkg-fslib/sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type {CreateWriteStreamOptions} from './FakeFS';
export type {Dirent, DirentNoPath, Dir, SymlinkType} from './FakeFS';
export type {MkdirOptions} from './FakeFS';
export type {ReaddirOptions} from './FakeFS';
export type {RmdirOptions} from './FakeFS';
export type {RmdirOptions, RmOptions} from './FakeFS';
export type {WatchOptions} from './FakeFS';
export type {WatchCallback} from './FakeFS';
export type {Watcher} from './FakeFS';
Expand Down
2 changes: 2 additions & 0 deletions packages/yarnpkg-fslib/sources/patchFs/patchFs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const SYNC_IMPLEMENTATIONS = new Set([
`realpathSync`,
`renameSync`,
`rmdirSync`,
`rmSync`,
`statSync`,
`symlinkSync`,
`truncateSync`,
Expand Down Expand Up @@ -68,6 +69,7 @@ const ASYNC_IMPLEMENTATIONS = new Set([
`readlinkPromise`,
`renamePromise`,
`rmdirPromise`,
`rmPromise`,
`statPromise`,
`symlinkPromise`,
`truncatePromise`,
Expand Down
30 changes: 29 additions & 1 deletion packages/yarnpkg-libzip/sources/ZipFS.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Dirent, DirentNoPath, ReaddirOptions} from '@yarnpkg/fslib';
import {WatchOptions, WatchCallback, Watcher, Dir, Stats, BigIntStats, StatSyncOptions, StatOptions} from '@yarnpkg/fslib';
import {FakeFS, MkdirOptions, RmdirOptions, WriteFileOptions, OpendirOptions} from '@yarnpkg/fslib';
import {FakeFS, MkdirOptions, RmdirOptions, RmOptions, WriteFileOptions, OpendirOptions} from '@yarnpkg/fslib';
import {CreateReadStreamOptions, CreateWriteStreamOptions, BasePortableFakeFS, ExtractHintOptions, WatchFileCallback, WatchFileOptions, StatWatcher} from '@yarnpkg/fslib';
import {NodeFS} from '@yarnpkg/fslib';
import {opendir} from '@yarnpkg/fslib';
Expand Down Expand Up @@ -1353,6 +1353,34 @@ export class ZipFS extends BasePortableFakeFS {

this.deleteEntry(p, index);
}
async rmPromise(p: PortablePath, opts?: RmOptions) {
return this.rmSync(p, opts);
}

rmSync(p: PortablePath, {recursive = false}: RmOptions = {}) {
if (this.readOnly)
throw errors.EROFS(`rm '${p}'`);

if (recursive) {
this.removeSync(p);
return;
}

const resolvedP = this.resolveFilename(`rm '${p}'`, p);

const directoryListing = this.listings.get(resolvedP);
if (!directoryListing)
throw errors.ENOTDIR(`rm '${p}'`);

if (directoryListing.size > 0)
throw errors.ENOTEMPTY(`rm '${p}'`);

const index = this.entries.get(resolvedP);
if (typeof index === `undefined`)
throw errors.EINVAL(`rm '${p}'`);

this.deleteEntry(p, index);
}

private hydrateDirectory(resolvedP: PortablePath) {
const index = this.libzip.dir.add(this.zip, ppath.relative(PortablePath.root, resolvedP));
Expand Down
10 changes: 9 additions & 1 deletion packages/yarnpkg-pnpify/sources/NodeModulesFS.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {BigIntStats, DirentNoPath, ReaddirOptions, Stats} from '@yarnpkg/fslib';
import {Dirent, Filename, MkdirOptions, ExtractHintOptions, WatchFileCallback, WatchFileOptions, StatWatcher, OpendirOptions, Dir} from '@yarnpkg/fslib';
import {RmdirOptions} from '@yarnpkg/fslib';
import {RmdirOptions, RmOptions} from '@yarnpkg/fslib';
import {FSPath, NativePath, PortablePath, npath, ppath, opendir} from '@yarnpkg/fslib';
import {WatchOptions, WatchCallback, Watcher} from '@yarnpkg/fslib';
import {NodeFS, FakeFS, WriteFileOptions, ProxiedFS} from '@yarnpkg/fslib';
Expand Down Expand Up @@ -471,6 +471,14 @@ export class PortableNodeModulesFS extends FakeFS<PortablePath> {
return this.baseFs.rmdirSync(this.resolveDirOrFilePath(p), opts);
}

async rmPromise(p: PortablePath, opts?: RmOptions) {
return await this.baseFs.rmPromise(this.resolveDirOrFilePath(p), opts);
}

rmSync(p: PortablePath, opts?: RmOptions) {
return this.baseFs.rmSync(this.resolveDirOrFilePath(p), opts);
}

async linkPromise(existingP: PortablePath, newP: PortablePath) {
return await this.baseFs.linkPromise(this.resolveDirOrFilePath(existingP), this.resolveDirOrFilePath(newP));
}
Expand Down

0 comments on commit 7627325

Please sign in to comment.