-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
fix(plugin-compat): update fsevents patch to support virtual path #1671
Merged
arcanis
merged 20 commits into
yarnpkg:master
from
missing1984:mluo/fix-fsevents-virtual-path
Aug 18, 2020
Merged
Changes from 7 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
48e0dc0
update fsevents patch to support virtual path
8eb79ad
update version
b1bb8b4
update patch
ce7f7a2
update patch
202140c
switch to use pnp.resolveVirtual
f653dbc
revert yarn.js
4e27756
update version
99024a7
Refactors the fsevents patch using a reverse map
arcanis 411d392
Updates artifacts
arcanis e7c7c9c
Fixes patch for 2.1.1
arcanis d471246
Use perl
arcanis bf77d82
Adds debug
arcanis 7e18b89
Merge branch 'master' into mluo/fix-fsevents-virtual-path
arcanis 4de6b1c
Fixes debug
arcanis 781ff65
Fixes workflow config
arcanis fc0dcf5
Adds debug artifacts
arcanis 938ec0c
Adds debug?
arcanis e95ef87
Adds guards around generation file size
arcanis ee2b36a
Removes debug
arcanis 3816be3
Update gen-typescript-patch.sh
arcanis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Binary file renamed
BIN
+14.1 KB
.../fsevents-patch-ef2bb5c6ad-0005677b72.zip → .../fsevents-patch-37d06552a3-972dc3797a.zip
Binary file not shown.
Binary file renamed
BIN
+804 KB
.../fsevents-patch-c16896bf90-d56427b46c.zip → .../fsevents-patch-bf25093668-bbf0b3dd84.zip
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
releases: | ||
"@yarnpkg/builder": patch | ||
"@yarnpkg/cli": patch | ||
"@yarnpkg/core": patch | ||
"@yarnpkg/doctor": patch | ||
"@yarnpkg/plugin-compat": patch | ||
"@yarnpkg/plugin-constraints": patch | ||
"@yarnpkg/plugin-dlx": patch | ||
"@yarnpkg/plugin-essentials": patch | ||
"@yarnpkg/plugin-exec": patch | ||
"@yarnpkg/plugin-file": patch | ||
"@yarnpkg/plugin-git": patch | ||
"@yarnpkg/plugin-github": patch | ||
"@yarnpkg/plugin-http": patch | ||
"@yarnpkg/plugin-init": patch | ||
"@yarnpkg/plugin-interactive-tools": patch | ||
"@yarnpkg/plugin-link": patch | ||
"@yarnpkg/plugin-node-modules": patch | ||
"@yarnpkg/plugin-npm": patch | ||
"@yarnpkg/plugin-npm-cli": patch | ||
"@yarnpkg/plugin-pack": patch | ||
"@yarnpkg/plugin-patch": patch | ||
"@yarnpkg/plugin-pnp": patch | ||
"@yarnpkg/plugin-stage": patch | ||
"@yarnpkg/plugin-typescript": patch | ||
"@yarnpkg/plugin-version": patch | ||
"@yarnpkg/plugin-workspace-tools": patch | ||
"@yarnpkg/pnp": patch | ||
"@yarnpkg/pnpify": patch | ||
vscode-zipfs: patch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
diff --git a/fsevents.js b/fsevents.js | ||
semver exclusivity 2.1.1 | ||
--- a/fsevents.js | ||
+++ b/fsevents.js | ||
@@ -21,12 +21,11 @@ function watch(path, handler) { | ||
throw new TypeError(`fsevents argument 2 must be a function and not a ${typeof handler}`); | ||
} | ||
|
||
- let instance = Native.start(path, handler); | ||
- if (!instance) throw new Error(`could not watch: ${path}`); | ||
+ let VFS = require('./vfs'); | ||
+ let vfs = new VFS(path, Native); | ||
+ vfs.watch(handler); | ||
return () => { | ||
- const result = instance ? Promise.resolve(instance).then(Native.stop) : null; | ||
- instance = null; | ||
- return result; | ||
+ return vfs.stop(); | ||
}; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,22 @@ | ||
diff --git a/fsevents.js b/fsevents.js | ||
semver exclusivity ^2.1 | ||
semver exclusivity ^2.1.2 | ||
--- a/fsevents.js | ||
+++ b/fsevents.js | ||
@@ -21,5 +21,7 @@ function watch(path, handler) { | ||
@@ -21,13 +21,10 @@ function watch(path, handler) { | ||
throw new TypeError(`fsevents argument 2 must be a function and not a ${typeof handler}`); | ||
} | ||
|
||
- let instance = Native.start(path, handler); | ||
- if (!instance) throw new Error(`could not watch: ${path}`); | ||
+ let VFS = require('./vfs'); | ||
+ let vfs = new VFS(path); | ||
+ let instance = Native.start(vfs.resolvedPath, vfs.wrap(handler)); | ||
if (!instance) throw new Error(`could not watch: ${path}`); | ||
+ let vfs = new VFS(path, Native); | ||
+ vfs.watch(handler); | ||
return () => { | ||
- const result = instance | ||
- ? Promise.resolve(instance).then(Native.stop) | ||
- : Promise.resolve(undefined); | ||
- instance = undefined; | ||
- return result; | ||
+ return vfs.stop(); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,45 +2,108 @@ diff --git a/vfs.js b/vfs.js | |
new file mode 100644 | ||
--- /dev/null | ||
+++ b/vfs.js | ||
@@ -0,0 +1,41 @@ | ||
@@ -0,0 +1,104 @@ | ||
+const path = require(`path`); | ||
+ | ||
+const NUMBER_REGEXP = /^[0-9]+$/; | ||
+const VIRTUAL_REGEXP = /^(\/(?:[^\/]+\/)*?\$\$virtual)((?:\/([^\/]+)(?:\/([^\/]+))?)?((?:\/.*)?))$/; | ||
+function getPnpApi() { | ||
+ let pnpApi; | ||
+ try { | ||
+ if (process.versions.pnp) { | ||
+ pnpApi = require(`pnpapi`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @arcanis I am assuming calling |
||
+ } | ||
+ } catch (ex) {} | ||
+ return pnpApi; | ||
+} | ||
+ | ||
+function resolveVirtual(p) { | ||
+ const match = p.match(VIRTUAL_REGEXP); | ||
+ if (!match) | ||
+ return p; | ||
+ | ||
+ const target = path.dirname(match[1]); | ||
+ if (!match[3] || !match[4]) | ||
+ return target; | ||
+ const pnpapi = getPnpApi(); | ||
+ if (pnpapi) { | ||
+ const resolved = pnpapi.resolveVirtual(p); | ||
+ // pnp resolveVirtual will return null for non-virtual path. | ||
+ return resolved == null ? p : resolved; | ||
+ } | ||
+ return p; | ||
+} | ||
+ | ||
+ const isnum = NUMBER_REGEXP.test(match[4]); | ||
+ if (!isnum) | ||
+ return p; | ||
+function findVirtualPaths(root) { | ||
+ const paths = []; | ||
+ const pnpapi = getPnpApi(); | ||
+ if (pnpapi) { | ||
+ for (const locator of pnpapi.getDependencyTreeRoots()) { | ||
+ const pkg = pnpapi.getPackageInformation(locator); | ||
+ for (const [name, referencish] of pkg.packageDependencies) { | ||
+ if (referencish === null) continue; | ||
+ if (referencish.indexOf(`virtual:`) === 0) { | ||
+ const virtualLocator = pnpapi.getLocator(name, referencish); | ||
+ const virtualPkg = pnpapi.getPackageInformation(virtualLocator); | ||
+ if (virtualPkg && virtualPkg.packageLocation.indexOf(root) === 0) { | ||
+ // virtual path fall under root | ||
+ paths.push(virtualPkg.packageLocation); | ||
+ } | ||
+ } | ||
+ } | ||
+ } | ||
+ } | ||
+ return paths; | ||
+} | ||
+ | ||
+ const depth = Number(match[4]); | ||
+ const backstep = `../`.repeat(depth); | ||
+ const subpath = (match[5] || `.`); | ||
+class VFS { | ||
+ constructor(p, Native) { | ||
+ this.root = path.resolve(p); | ||
+ this.native = Native; | ||
+ this.watchers = []; | ||
+ } | ||
+ | ||
+ return resolveVirtual(path.join(target, backstep, subpath)); | ||
+} | ||
+ transpose(rawPath, resolvedPath, p) { | ||
+ const transposePath = rawPath + p.substr(resolvedPath.length); | ||
+ return transposePath; | ||
+ } | ||
+ | ||
+module.exports = class FsePnp { | ||
+ constructor(p) { | ||
+ this.normalizedPath = path.resolve(p); | ||
+ this.resolvedPath = resolveVirtual(this.normalizedPath); | ||
+ /** | ||
+ * build raw and resolved path mapping | ||
+ * @param {*} root | ||
+ */ | ||
+ buildPathMap() { | ||
+ const pathMap = new Map(); | ||
+ this.resolvedRoot = resolveVirtual(this.root); | ||
+ pathMap.set(this.resolvedRoot, this.root); | ||
+ if (!path.extname(this.root)) { | ||
+ // find all direct virtual paths for given root. | ||
+ const virtualPaths = findVirtualPaths(this.root); | ||
+ virtualPaths.forEach((virtualPath) => { | ||
+ const resolvedVirtual = resolveVirtual(virtualPath); | ||
+ if (resolvedVirtual.indexOf(this.resolvedRoot) < 0) { | ||
+ pathMap.set(resolvedVirtual, virtualPath); | ||
+ } | ||
+ }); | ||
+ } | ||
+ return pathMap; | ||
+ } | ||
+ | ||
+ transpose(p) { | ||
+ return this.normalizedPath + p.substr(this.resolvedPath.length); | ||
+ watch(handler) { | ||
+ const pathMap = this.buildPathMap(); | ||
+ pathMap.forEach((virtualPath, resolvedPath) => { | ||
+ const watcher = this.native.start(resolvedPath, (p, ...args) => { | ||
+ return handler(this.transpose(virtualPath, resolvedPath, p), ...args); | ||
+ }); | ||
arcanis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
+ if (!watcher) throw new Error(`could not watch: ${resolvedPath}`); | ||
+ this.watchers.push(watcher); | ||
+ }); | ||
+ return this.watchers; | ||
+ } | ||
+ | ||
+ wrap(fn) { | ||
+ return (path, ...args) => { | ||
+ return fn(this.transpose(path), ...args); | ||
+ }; | ||
+ stop() { | ||
+ const results = this.watchers.map((watcher) => { | ||
+ const p = Promise.resolve(watcher); | ||
+ if (watcher) { | ||
+ p.then(this.native.stop); | ||
+ } | ||
+ return p; | ||
+ }); | ||
+ this.watchers = []; | ||
+ this.resolvedRoot = undefined; | ||
+ return results[0]; | ||
+ } | ||
+}; | ||
+} | ||
+ | ||
+module.exports = VFS; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the API fsevents 1.x exposed makes it quite challenging to watch multiple files so I only watch the path file instead.( same behavior as current patch)