Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Fix global type loading on Windows paths #362

Merged
merged 10 commits into from
Oct 9, 2017

Conversation

tomv564
Copy link
Contributor

@tomv564 tomv564 commented Oct 3, 2017

This PR now contains 3 fixes for Windows path handling caused by two inconsistencies

The first inconsistency existed between expectedFiles (unix paths) and typeRoots (windows paths)

Typings from e.g. jasmine/mocha not resolved by Typescript

Repro: Open any test file in this project, receive diagnostics about not finding it and describe
Cause: Files were loaded in memory, but ensureBasicFiles passed windows paths into unix-style path filters (isGlobalTsFile).
Fix: Convert to unix paths before passing to filter methods in ensureBasicFiles (7f57e21)
Test: ✅ Added in 6d9d3d0

After this fix, isExpectedDeclarationFile now expected a unixPath, causing a new issue:

Typings from typeRoots not resolved by Typescript

Repro: Open a project using typeRoots, receive diagnostics about not finding types from typeRoots
Cause: Files from typeRoots were not loaded into memory by ensureConfigDependencies as it was still passing Windows paths into the now unix-path-based isConfigDependency
Fix: Make typeRoots unix-path based so it is consistent with checks against expectedFiles. (f0c8e02)
Test: ✅ Updated to check host in 6d9d3d0

This fixed the type resolution issues I had been seeing while working on Windows. 🎉

To add test coverage, I made the ProjectManager tests use different rootUris. This did not cover the above issues, but it did uncover another inconsistency:

Windows rootPath not handled correctly for configuration lookups in ProjectManager

When ProjectManager is constructed with a Windows rootPath:

  • It is not trimmed correctly (see trimmedRootPath)
  • It puts Windows paths into this.configs which otherwise uses unix paths.

Impact: My guess is default configurations did not work on windows, as they were windows-style and the rest of the code assumed unix-style paths were used..
Fix: Handle rootPath and configuration lookups in a platform-sensitive way (because there is no need to normalise to unix paths here?)

@codecov
Copy link

codecov bot commented Oct 3, 2017

Codecov Report

Merging #362 into master will decrease coverage by 0.05%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #362      +/-   ##
==========================================
- Coverage   74.68%   74.63%   -0.06%     
==========================================
  Files          15       15              
  Lines        1758     1758              
  Branches      331      331              
==========================================
- Hits         1313     1312       -1     
- Misses        294      295       +1     
  Partials      151      151
Impacted Files Coverage Δ
src/project-manager.ts 81.28% <100%> (-0.62%) ⬇️
src/match-files.ts 66.66% <0%> (+0.49%) ⬆️

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 c5902d7...5fc67b6. Read the comment docs.

@tomv564
Copy link
Contributor Author

tomv564 commented Oct 7, 2017

@felixfbecker would you want to have a look at this? Not a clean diff, but I hope the comments above help explain.

The main design issue I tried to solve is knowing when windows paths are converted to unix paths, my guidelines for solving the inconsistency were:

  • ProjectManager uses Windows paths as it interacts more with the filesystem.
  • ProjectConfiguration uses unixPaths as it works closely with the typescript configuration/library which use unix paths on windows.

while (dir && dir !== rootPath) {
config = configs.get(dir)
if (config) {
return config
}
const pos = dir.lastIndexOf('/')
const pos = dir.includes('\\') ? dir.lastIndexOf('\\') : dir.lastIndexOf('/')
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd use string.search()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definitely more compact:

filePath.search(/[\\\/][^\\\/]*$/)

Do you prefer this? If so, I propose storing the regex as a static member somewhere (or adding this functionality to util.ts.

import { MapFileSystem } from './fs-helpers'
chai.use(chaiAsPromised)
const assert = chai.assert

describe('ProjectManager', () => {
for (const rootUri of ['file:///', 'file:///c:/foo/bar/', 'file:///foo/bar/']) {
testWithRootUri(rootUri)
Copy link
Contributor

Choose a reason for hiding this comment

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

why not inline this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed (if I understood correctly)

@felixfbecker
Copy link
Contributor

  • ProjectManager uses Windows paths as it interacts more with the filesystem.
  • ProjectConfiguration uses unixPaths as it works closely with the typescript configuration/library which use unix paths on windows.

Could you make this documentation available in the source code somewhere, e.g. in the docblock of the respective classes?

@tomv564
Copy link
Contributor Author

tomv564 commented Oct 8, 2017

For visibility I propose adding it on every docblock that describes a field/parameter.

I wish typing could help with this, eg

type UnixPath: string

An option is to use interface UnixPath extends string, but this requires code changes.
What do you prefer?

@tomv564
Copy link
Contributor Author

tomv564 commented Oct 9, 2017

@felixfbecker your suggestions were applied, ready for your review again!

@@ -24,6 +24,8 @@ import {
uri2path
} from './util'

const LastForwardOrBackwardSlash = /[\\\/][^\\\/]*$/
Copy link
Contributor

Choose a reason for hiding this comment

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

use CONSTANT_CASE

Copy link
Contributor

@felixfbecker felixfbecker left a comment

Choose a reason for hiding this comment

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

LGTM other than the casing comment

@felixfbecker felixfbecker merged commit 6fcc4e1 into sourcegraph:master Oct 9, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants