Skip to content

Update the code base to use IFileSystem instead of fs and fs-extra. #7915

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

Merged

Conversation

ericsnowcurrently
Copy link

(for #6911)

This is a precursor to the actual fix. It ensures that we really do use the new FS API everywhere.

I've left out changes related to datascience. I'll open a separate issue for that.

  • Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR)
  • Title summarizes what is changing
  • [ ] Has a news entry file (remember to thank yourself!)
  • Appropriate comments and documentation strings in the code
  • [ ] Has sufficient logging.
  • [ ] Has telemetry for enhancements.
  • Unit tests & system/integration tests are added/updated
  • [ ] Test plan is updated as appropriate
  • [ ] package-lock.json has been regenerated by running npm install (if dependencies have changed)
  • [ ] The wiki is updated with any design decisions/details.

@ericsnowcurrently ericsnowcurrently added the no-changelog No news entry required label Oct 10, 2019
@ericsnowcurrently ericsnowcurrently force-pushed the consolidate-fs-usage branch 2 times, most recently from 37906bf to 5aae7b5 Compare October 21, 2019 19:40
@codecov-io
Copy link

codecov-io commented Oct 21, 2019

Codecov Report

Merging #7915 into master will decrease coverage by 0.02%.
The diff coverage is 69.09%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #7915      +/-   ##
==========================================
- Coverage    58.1%   58.07%   -0.03%     
==========================================
  Files         527      526       -1     
  Lines       27075    26827     -248     
  Branches     4043     4040       -3     
==========================================
- Hits        15731    15581     -150     
+ Misses      10485    10389      -96     
+ Partials      859      857       -2
Impacted Files Coverage Δ
...rc/client/debugger/debugAdapter/serviceRegistry.ts 0% <ø> (ø) ⬆️
src/client/sourceMapSupport.ts 81.25% <ø> (ø) ⬆️
.../datascience/interactive-common/interactiveBase.ts 24.79% <0%> (ø) ⬆️
...rpreter/locators/services/baseVirtualEnvService.ts 28.3% <0%> (ø) ⬆️
src/client/datascience/jupyter/kernelService.ts 55.1% <100%> (ø) ⬆️
src/client/common/net/fileDownloader.ts 100% <100%> (ø) ⬆️
src/client/common/variables/environment.ts 92.4% <100%> (+0.09%) ⬆️
src/client/common/platform/serviceRegistry.ts 100% <100%> (ø) ⬆️
src/client/common/platform/types.ts 100% <100%> (ø) ⬆️
...preter/locators/services/windowsRegistryService.ts 90% <100%> (ø) ⬆️
... and 48 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9411e98...5eb00e1. Read the comment docs.

Copy link

@kimadeline kimadeline left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple of questions, otherwise it looks good. The intermediate state of fileSystem.ts is a bit 😬, looking forward to seeing its final form :D

}

public async rmtree(dirname: string): Promise<void> {
return this.fsExtra.rmdir(dirname);
return this.fsExtra.stat(dirname)
Copy link

@DonJayamanne DonJayamanne Oct 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we performing a check here.
This doesn't look right. The calling code should not be invoking this method if the directory doesn't exists. I.e. calling code shoudl fall over if its called incorrectly.
Basically we're swallowing exceptions here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because fsextra.remove() does not fail if the directory does not exist. Therefore we have to do the manual check.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we to try and delete and swallow exceptions if any.
That's faster than checking file info then deleting. I.e. perform one I/O operation


export class FileSystemPath implements IFileSystemPath {
constructor(
private readonly isWindows = (getOSType() === OSType.Windows),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this an optional parameter?
Looks like code smell again!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default value captures the normal use case.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the other use case?

return this.raw.join(...filenames);
}

public normCase(filename: string): string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this? Is this something VS Code API has added or are we bringing in something from python world in here? I know we're had a tonne of issues with normcase in debugger and pytest adapter, and not looking forward to introducing an unnecessary complication in the node/extension world
@karthiknadig (you know about the norm case issues in debugger better than me)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking if it is platform is not sufficient on windows. Individual folders can have case-sensitive settings enabled on them. I would leave this to platform APIs or VS Code itself to figure out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This covers the logic from existing. All I'm doing is pulling it out into an explicit function. If it's a problem then it's an existing problem. In that case please open a separate issue.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why create a method for this, when all we need is a way to compare paths and we have a simple meeting already. I.e. when else would norm case be used?

private readonly isWindows = (getOSType() === OSType.Windows),
//public readonly raw: IFileSystem = {}
public readonly raw: IRawFileSystem = new RawFileSystem()
public readonly raw: IRawFileSystem = new RawFileSystem(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't see why we are injecting parameters with default values?
This isn't node style code! Seems like this is written specially for testing purposes, These should be injected using DI.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unclear on the problem here. We can talk about the topic more, but I'd rather get this PR merged first.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DonJayamanne do you have a link on that? I couldn't find relevant answers on the internet 🕵️‍♀️ Personally I'm not a big fan of instantiating objects/complex values as default parameters.

Copy link

@DonJayamanne DonJayamanne Oct 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.
This had been discussed with the broader team (including DS) and we agreed this isn't something we'd continue doing.
Ideal we should remove this default parameters, been discussed

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'm not a big fan of instantiating objects/complex values as default parameters

I'll update our standing standards guide (with what was discussed and decided) so there no confusion.

Copy link

@DonJayamanne DonJayamanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not add normcase API/function if not required.
Other comments are optional, though we agreed not to go with default parameters for testing purposes.

}
path1 = this.path.normCase(path1);
path2 = this.path.normCase(path2);
return path1 === path2;
Copy link
Member

@karthiknadig karthiknadig Oct 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comparison may be incorrect. What this is checking is if the strings are the same, not really the paths. What happens if the path1 is short-path and path2 is long path to the same file? This should at minimum expand to long path on windows. I would defer this to platform APIs as well. Old implementation was incorrect as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please open a separate issue for this.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a way to compare file paths today. This sounds and looks like python style norm casing.
It's called arePathsSame or similar.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I.e. there's never a need to do norm casing, this should be done only when comparing paths and we have a simple generic method for that today.

@ericsnowcurrently
Copy link
Author

trigger re-test

Copy link

@kimadeline kimadeline left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple of questions, but I also disagree with the way you've structured your tests: since some of your tests are wrapped in if/else conditions, it means that the test suites are not idempotent since they are not hitting each test no matter the platform and skipping them as needed (i hope i'm using that word correctly 😬).

@ericsnowcurrently ericsnowcurrently force-pushed the consolidate-fs-usage branch 2 times, most recently from 78fc42e to 83ae768 Compare November 4, 2019 21:34
getRealPath(path: string): Promise<string>;
export interface IFileSystemPath {
join(...filenames: string[]): string;
normCase(filename: string): string;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't used.

@kimadeline
Copy link

Why did the GH VS Code extension publish my comments as single reviews even though they were marked as "pending" (╯°□°)╯︵ ┻━┻

@ericsnowcurrently ericsnowcurrently merged commit a23761d into microsoft:master Nov 26, 2019
@ericsnowcurrently ericsnowcurrently deleted the consolidate-fs-usage branch November 26, 2019 01:11
@lock lock bot locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
no-changelog No news entry required
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants