diff --git a/.yarn/versions/ec8c3499.yml b/.yarn/versions/ec8c3499.yml new file mode 100644 index 000000000000..68f6ae19e503 --- /dev/null +++ b/.yarn/versions/ec8c3499.yml @@ -0,0 +1,35 @@ +releases: + "@yarnpkg/cli": prerelease + "@yarnpkg/core": prerelease + "@yarnpkg/fslib": prerelease + +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-http" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-link" + - "@yarnpkg/plugin-node-modules" + - "@yarnpkg/plugin-npm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - vscode-zipfs + - "@yarnpkg/builder" + - "@yarnpkg/doctor" + - "@yarnpkg/json-proxy" + - "@yarnpkg/pnp" + - "@yarnpkg/pnpify" + - "@yarnpkg/shell" diff --git a/packages/yarnpkg-core/sources/tgzUtils.ts b/packages/yarnpkg-core/sources/tgzUtils.ts index 2c14fb986530..a491765d9060 100644 --- a/packages/yarnpkg-core/sources/tgzUtils.ts +++ b/packages/yarnpkg-core/sources/tgzUtils.ts @@ -108,7 +108,7 @@ export async function extractArchiveTo>(tgz: Buff targetFs.mkdirpSync(ppath.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); targetFs.symlinkSync(entry.linkpath, mappedPath); - targetFs.lutimesSync!(mappedPath, defaultTime, defaultTime); + targetFs.lutimesSync?.(mappedPath, defaultTime, defaultTime); } break; } }); diff --git a/packages/yarnpkg-fslib/sources/NodeFS.ts b/packages/yarnpkg-fslib/sources/NodeFS.ts index 41a0cc873cba..fae2361a2746 100644 --- a/packages/yarnpkg-fslib/sources/NodeFS.ts +++ b/packages/yarnpkg-fslib/sources/NodeFS.ts @@ -4,6 +4,7 @@ import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; import {Dirent, SymlinkType} from './FakeFS'; import {BasePortableFakeFS, WriteFileOptions} from './FakeFS'; import {MkdirOptions, WatchOptions, WatchCallback, Watcher} from './FakeFS'; +import {ENOSYS} from './errors'; import {FSPath, PortablePath, Filename, npath} from './path'; export class NodeFS extends BasePortableFakeFS { @@ -13,6 +14,12 @@ export class NodeFS extends BasePortableFakeFS { super(); this.realFs = realFs; + + // @ts-ignore + if (typeof this.realFs.lutimes !== `undefined`) { + this.lutimesPromise = this.lutimesPromiseImpl; + this.lutimesSync = this.lutimesSyncImpl; + } } getExtractHint() { @@ -233,6 +240,26 @@ export class NodeFS extends BasePortableFakeFS { this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); } + private async lutimesPromiseImpl(this: NodeFS, p: PortablePath, atime: Date | string | number, mtime: Date | string | number) { + // @ts-ignore: Not yet in DefinitelyTyped + const lutimes = this.realFs.lutimes; + if (typeof lutimes === `undefined`) + throw ENOSYS(`unavailable Node binding`, `lutimes '${p}'`); + + return await new Promise((resolve, reject) => { + lutimes.call(this.realFs, npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); + }); + } + + private lutimesSyncImpl(this: NodeFS, p: PortablePath, atime: Date | string | number, mtime: Date | string | number) { + // @ts-ignore: Not yet in DefinitelyTyped + const lutimesSync = this.realFs.lutimesSync; + if (typeof lutimesSync === `undefined`) + throw ENOSYS(`unavailable Node binding`, `lutimes '${p}'`); + + lutimesSync.call(this.realFs, npath.fromPortablePath(p), atime, mtime); + } + async mkdirPromise(p: PortablePath, opts?: MkdirOptions) { return await new Promise((resolve, reject) => { this.realFs.mkdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); diff --git a/packages/yarnpkg-fslib/sources/algorithms/copyPromise.ts b/packages/yarnpkg-fslib/sources/algorithms/copyPromise.ts index c62ba705884d..43b4b017b46b 100644 --- a/packages/yarnpkg-fslib/sources/algorithms/copyPromise.ts +++ b/packages/yarnpkg-fslib/sources/algorithms/copyPromise.ts @@ -32,7 +32,6 @@ export async function copyPromise(destinationF : destinationFs.utimesPromise.bind(destinationFs); for (const [p, atime, mtime] of lutimes) { - // await destinationFs.utimesPromise(p, atime, mtime); await updateTime!(p, atime, mtime); } } diff --git a/packages/yarnpkg-fslib/sources/index.ts b/packages/yarnpkg-fslib/sources/index.ts index 884332d78438..a0c9e593505a 100644 --- a/packages/yarnpkg-fslib/sources/index.ts +++ b/packages/yarnpkg-fslib/sources/index.ts @@ -53,6 +53,7 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void `closeSync`, `copyFileSync`, `lstatSync`, + `lutimesSync`, `mkdirSync`, `openSync`, `readSync`, @@ -79,6 +80,7 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void `closePromise`, `copyFilePromise`, `lstatPromise`, + `lutimesPromise`, `mkdirPromise`, `openPromise`, `readdirPromise`, @@ -98,10 +100,8 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void const setupFn = (target: any, name: string, replacement: any) => { const orig = target[name]; - if (typeof orig === `undefined`) - return; - target[name] = replacement; + if (typeof orig[promisify.custom] !== `undefined`) { replacement[promisify.custom] = orig[promisify.custom]; } @@ -142,28 +142,40 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void }); for (const fnName of ASYNC_IMPLEMENTATIONS) { - const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); const origName = fnName.replace(/Promise$/, ``); + if (typeof (patchedFs as any)[origName] === `undefined`) + continue; + + const fakeImpl: Function = (fakeFs as any)[fnName]; + if (typeof fakeImpl === `undefined`) + continue; - setupFn(patchedFs, origName, (...args: Array) => { + const wrapper = (...args: Array) => { const hasCallback = typeof args[args.length - 1] === `function`; const callback = hasCallback ? args.pop() : () => {}; process.nextTick(() => { - fakeImpl(...args).then((result: any) => { + fakeImpl.apply(fakeFs, args).then((result: any) => { callback(null, result); }, (error: Error) => { callback(error); }); }); - }); + }; + + setupFn(patchedFs, origName, wrapper); } for (const fnName of SYNC_IMPLEMENTATIONS) { - const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); const origName = fnName; + if (typeof (patchedFs as any)[origName] === `undefined`) + continue; + + const fakeImpl: Function = (fakeFs as any)[fnName]; + if (typeof fakeImpl === `undefined`) + continue; - setupFn(patchedFs, origName, fakeImpl); + setupFn(patchedFs, origName, fakeImpl.bind(fakeFs)); } patchedFs.realpathSync.native = patchedFs.realpathSync;