-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Added Windows store file system watcher #14577
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
Conversation
Codecov Report
@@ Coverage Diff @@
## main #14577 +/- ##
==========================================
- Coverage 64.91% 64.88% -0.03%
==========================================
Files 541 541
Lines 25131 25156 +25
Branches 3544 3545 +1
==========================================
+ Hits 16313 16323 +10
- Misses 8155 8171 +16
+ Partials 663 662 -1
Continue to review full report at Codecov.
|
* python2.7.exe | ||
* python3.exe | ||
* python38.exe | ||
* Note the below is constructed in a way that it can be used as a glob pattern, or as a regex. |
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.
...
bf48246
to
1461297
Compare
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 major comments:
- why are we using globs instead of regexes?
- do not start the watcher in the constructor
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Show resolved
Hide resolved
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
3994c45
to
d4818ea
Compare
@ericsnowcurrently The glob module that we use is built on top of |
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.
Overall this is looking good. Thanks for the fixes. I've left a few minor comments in the non-test files. Otherwise all the rest of the comments are in the test files.
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
): void { | ||
const patterns = [executableGlob, `*/${executableGlob}`, `*/${binName}/${executableGlob}`]; |
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.
It would be helpful to callers to throw an error here if executableGlob
has path.separator
in it. I still think a similar check for wildcards (*
) would be likewise helpful.
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.
I went with your initial suggestion to expand the glob pattern to support more than base patterns. #14577 (comment)
So we don't have to put a restriction on the wildcards or path separators. I can rename it to executableSuffixGlob
if that would help.
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.
I went with your initial suggestion to expand the glob pattern to support more than base patterns.
I don't see that. What I see is:
const pythonExeGlob = 'python3\.[0-9]*\.exe';
A more-than-base pattern would be:
const pythonExeGlob = '**/python3\.[0-9]*\.exe';
or:
const pythonExeGlob = path.join('**', 'python3\.[0-9]*\.exe');
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.
I'm talking about the API, not this particular usecase. The API supports more than base patterns, i.e user can pass in a path.join('**', 'python3\.[0-9]*\.exe')
and things should work. Just needed to do this here.
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.
path.join('**', executablesGlob)
is exactly what I would expect this function to do for the caller.
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.
I think you're assuming executablesGlob
to be the base executable glob, it's not. It refers to the suffix of the full executable path we intend to watch. For eg. it can be path.join('**', 'python3\.[0-9]*\.exe')
itself, so the function need not do anything for the caller.
Hence why I suggested to rename it to executablesSuffixGlob
.
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 patterns on this line suggest otherwise:
executableGlob
- look for the file in the current directory*/${executableGlob}
- look for the file one level down*/${binName}/${executableGlob}
- look for the file in the "bin" directory one level down
What you seen to be saying is that a caller may want to search at some arbitrary depth relative to a given root:
**/python3.exe
*/**/python3.exe
*/${binName}/**/python3.exe
However, those don't seem right to me. Perhaps you meant a user might want to do something like the following?
**/python3.exe
**/*/python3.exe
**/*/${binName}/python3.exe
The problem is that kind of defeats the structure-oriented design of this function. So I don't see that to be right either.
All this is why I would expect executableGlob
to always be a base name.
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.
What you seen to be saying is that a caller may want to search at some arbitrary depth relative to a given root:
**/python3.exe
*/**/python3.exe
*/${binName}/**/python3.exe
However, those don't seem right to me.
I realize it doesn't seem right. But if you look closely, the first pattern is enough to do what the user asks (watch for suffixes ending with python3.exe
). And the second and third pattern are just subsets of the first. So yes, they do what the user intended to.
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.
That is only true if the glob is for the basename. If they put **/...
then it won't be what they expect. If it shouldn't matter then this function should not be auto-watching */${executableGlob}
and */${binName}/${executableGlob}
. The two things just don't make sense together.
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Show resolved
Hide resolved
src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts
Outdated
Show resolved
Hide resolved
src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts
Show resolved
Hide resolved
src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts
Outdated
Show resolved
Hide resolved
src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts
Outdated
Show resolved
Hide resolved
src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts
Outdated
Show resolved
Hide resolved
src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts
Show resolved
Hide resolved
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.
I only have a few more minor comments. So...
LGTM once all the open comments have been addressed.
export function isWindowsStorePythonExe(interpreterPath: string): boolean { | ||
return minimatch(path.basename(interpreterPath), pythonExeGlob, { nocase: true }); | ||
} |
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.
Why aren't we just using isWindowsPythonExe()
?
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.
Because of the reason mentioned in the sprint demo today: We're matching only python3.*.exes
so that we do collect only unique executables. isWindowsPythonExe()
also matches with python.exe
which is not what we want.
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 doc comment explains this.
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.
Then I'd expect the following to take care of it:
export function isWindowsStorePythonExe(interpreterPath: string): boolean { | |
return minimatch(path.basename(interpreterPath), pythonExeGlob, { nocase: true }); | |
} | |
export function isWindowsStorePythonExe(interpreterPath: string): boolean { | |
if (!isWindowsPythonExe(interpreterPath)) { | |
return false; | |
} | |
return path.basename(interpreterPath) !== 'python.exe'; | |
} |
That way we don't accept executables we shouldn't, like "python3-whoa!!!.exe".
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.
Right, there's also python3.exe
, and python2.exe
that we would need to ignore. I can either do this or correct the glob pattern to not accept the whoaaa string. I'll have to correct the glob either way so we don't watch for such executables.
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.
Ah, so we're okay with "extended glob". What you have looks fine, but I'd change the *
to ?
.
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Show resolved
Hide resolved
src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts
Outdated
Show resolved
Hide resolved
const windowsAppsRoot = getWindowsStoreAppsRoot(); | ||
watchLocationForPythonBinaries(windowsAppsRoot, (type: FileChangeType) => { | ||
this.emitter.fire({ type, kind: this.kind }); | ||
}, pythonExeGlob); |
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.
Note that this is really the only place that we need pythonExeGlob
. So it may make sense to move it inline here.
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.
We need it in isWindowsStorePythonExe
as well.
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.
If we use isWindowsPythonExe()
there then only need it here.
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.
But then we would have two places where we capture what a windows store executable is? The glob pattern itself and isWindowsStorePythonExe
.
If we only use the glob, that way we have the logic in one central place.
Kudos, SonarCloud Quality Gate passed!
|
@ericsnowcurrently I believe I have addressed all the comments. I generally like to keep comments open for the reviewers to resolve them themselves. Hope I addressed most of your concerns. |
No description provided.