From 0ce0afcd97d33f07115986fb4b4d08b3107ed7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 17:11:21 +0200 Subject: [PATCH 1/7] Fixes lutimes for tgz extraction --- packages/yarnpkg-core/sources/tgzUtils.ts | 11 ++++++++++- packages/yarnpkg-fslib/sources/NodeFS.ts | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/yarnpkg-core/sources/tgzUtils.ts b/packages/yarnpkg-core/sources/tgzUtils.ts index 2c14fb986530..ca0753ebf7ee 100644 --- a/packages/yarnpkg-core/sources/tgzUtils.ts +++ b/packages/yarnpkg-core/sources/tgzUtils.ts @@ -108,7 +108,16 @@ 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); + + if (typeof targetFs.lutimesSync !== `undefined`) { + try { + targetFs.lutimesSync(mappedPath, defaultTime, defaultTime); + } catch (error) { + if (error !== `ENOSYS`) { + throw error; + } + } + } } break; } }); diff --git a/packages/yarnpkg-fslib/sources/NodeFS.ts b/packages/yarnpkg-fslib/sources/NodeFS.ts index 41a0cc873cba..14ec6def7f4f 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 { @@ -233,6 +234,26 @@ export class NodeFS extends BasePortableFakeFS { this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); } + async lutimesPromise(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)); + }); + } + + lutimesSync(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)); From 91eb15e306a0afa677ea0a3b8a0b247afc41d234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 17:19:23 +0200 Subject: [PATCH 2/7] Versions --- .yarn/versions/ec8c3499.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .yarn/versions/ec8c3499.yml 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" From ba6772a7014fdbf5c1350b0439b15c0918d31a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 17:53:46 +0200 Subject: [PATCH 3/7] Don't set lutimes if lutimes isn't there --- packages/yarnpkg-core/sources/tgzUtils.ts | 11 +---------- packages/yarnpkg-fslib/sources/NodeFS.ts | 8 ++++---- .../yarnpkg-fslib/sources/algorithms/copyPromise.ts | 1 - packages/yarnpkg-fslib/sources/index.ts | 2 ++ 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/packages/yarnpkg-core/sources/tgzUtils.ts b/packages/yarnpkg-core/sources/tgzUtils.ts index ca0753ebf7ee..a491765d9060 100644 --- a/packages/yarnpkg-core/sources/tgzUtils.ts +++ b/packages/yarnpkg-core/sources/tgzUtils.ts @@ -108,16 +108,7 @@ export async function extractArchiveTo>(tgz: Buff targetFs.mkdirpSync(ppath.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); targetFs.symlinkSync(entry.linkpath, mappedPath); - - if (typeof targetFs.lutimesSync !== `undefined`) { - try { - targetFs.lutimesSync(mappedPath, defaultTime, defaultTime); - } catch (error) { - if (error !== `ENOSYS`) { - throw error; - } - } - } + targetFs.lutimesSync?.(mappedPath, defaultTime, defaultTime); } break; } }); diff --git a/packages/yarnpkg-fslib/sources/NodeFS.ts b/packages/yarnpkg-fslib/sources/NodeFS.ts index 14ec6def7f4f..c193bcbeca69 100644 --- a/packages/yarnpkg-fslib/sources/NodeFS.ts +++ b/packages/yarnpkg-fslib/sources/NodeFS.ts @@ -234,7 +234,7 @@ export class NodeFS extends BasePortableFakeFS { this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); } - async lutimesPromise(p: PortablePath, atime: Date | string | number, mtime: Date | string | number) { + lutimesPromise = (`lutimesSync` in this.realFs) ? async function lutimesPromise(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`) @@ -243,16 +243,16 @@ export class NodeFS extends BasePortableFakeFS { return await new Promise((resolve, reject) => { lutimes.call(this.realFs, npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); }); - } + } : undefined; - lutimesSync(p: PortablePath, atime: Date | string | number, mtime: Date | string | number) { + lutimesSync = (`lutimesSync` in this.realFs) ? function lutimesSync(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); - } + } : undefined; async mkdirPromise(p: PortablePath, opts?: MkdirOptions) { return await new Promise((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..eac865582852 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`, From 0a60ed92b3f66c33791804d439d02731bceb0a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 18:00:41 +0200 Subject: [PATCH 4/7] Fixes definition --- packages/yarnpkg-fslib/sources/NodeFS.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/yarnpkg-fslib/sources/NodeFS.ts b/packages/yarnpkg-fslib/sources/NodeFS.ts index c193bcbeca69..fae2361a2746 100644 --- a/packages/yarnpkg-fslib/sources/NodeFS.ts +++ b/packages/yarnpkg-fslib/sources/NodeFS.ts @@ -14,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() { @@ -234,7 +240,7 @@ export class NodeFS extends BasePortableFakeFS { this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); } - lutimesPromise = (`lutimesSync` in this.realFs) ? async function lutimesPromise(this: NodeFS, p: PortablePath, atime: Date | string | number, mtime: Date | string | number) { + 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`) @@ -243,16 +249,16 @@ export class NodeFS extends BasePortableFakeFS { return await new Promise((resolve, reject) => { lutimes.call(this.realFs, npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); }); - } : undefined; + } - lutimesSync = (`lutimesSync` in this.realFs) ? function lutimesSync(this: NodeFS, p: PortablePath, atime: Date | string | number, mtime: Date | string | number) { + 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); - } : undefined; + } async mkdirPromise(p: PortablePath, opts?: MkdirOptions) { return await new Promise((resolve, reject) => { From 06ad17ff3228767c7abfd883c2513ee66a058be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 18:34:19 +0200 Subject: [PATCH 5/7] Fixes attachment --- packages/yarnpkg-fslib/sources/index.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/yarnpkg-fslib/sources/index.ts b/packages/yarnpkg-fslib/sources/index.ts index eac865582852..aaaaa194d4d8 100644 --- a/packages/yarnpkg-fslib/sources/index.ts +++ b/packages/yarnpkg-fslib/sources/index.ts @@ -100,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]; } @@ -144,10 +142,11 @@ 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; - setupFn(patchedFs, origName, (...args: Array) => { + const wrapper = (...args: Array) => { const hasCallback = typeof args[args.length - 1] === `function`; const callback = hasCallback ? args.pop() : () => {}; @@ -158,13 +157,18 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void callback(error); }); }); - }); + }; + + const fakeImpl: Function = (fakeFs as any)[fnName]; + 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]; setupFn(patchedFs, origName, fakeImpl); } From 3404cee52423c8ce1b6d4ff08bdb3c2898bf78bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 19:24:06 +0200 Subject: [PATCH 6/7] Restores the bind --- packages/yarnpkg-fslib/sources/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/yarnpkg-fslib/sources/index.ts b/packages/yarnpkg-fslib/sources/index.ts index aaaaa194d4d8..76f4a78a2bb0 100644 --- a/packages/yarnpkg-fslib/sources/index.ts +++ b/packages/yarnpkg-fslib/sources/index.ts @@ -159,7 +159,7 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void }); }; - const fakeImpl: Function = (fakeFs as any)[fnName]; + const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); setupFn(patchedFs, origName, wrapper); } @@ -168,7 +168,7 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void if (typeof (patchedFs as any)[origName] === `undefined`) continue; - const fakeImpl: Function = (fakeFs as any)[fnName]; + const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); setupFn(patchedFs, origName, fakeImpl); } From ce12f56f04959c47791042721c8bd3691ce2aa9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 14 May 2020 22:40:07 +0200 Subject: [PATCH 7/7] Fixes tests w/ graceful-fs --- packages/yarnpkg-fslib/sources/index.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/yarnpkg-fslib/sources/index.ts b/packages/yarnpkg-fslib/sources/index.ts index 76f4a78a2bb0..a0c9e593505a 100644 --- a/packages/yarnpkg-fslib/sources/index.ts +++ b/packages/yarnpkg-fslib/sources/index.ts @@ -146,12 +146,16 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void if (typeof (patchedFs as any)[origName] === `undefined`) continue; + const fakeImpl: Function = (fakeFs as any)[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + 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); @@ -159,7 +163,6 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void }); }; - const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); setupFn(patchedFs, origName, wrapper); } @@ -168,8 +171,11 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void if (typeof (patchedFs as any)[origName] === `undefined`) continue; - const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); - setupFn(patchedFs, origName, fakeImpl); + const fakeImpl: Function = (fakeFs as any)[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + + setupFn(patchedFs, origName, fakeImpl.bind(fakeFs)); } patchedFs.realpathSync.native = patchedFs.realpathSync;