Skip to content
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

Ignore the language server if the platform is not supported. #2351

Merged

Conversation

ericsnowcurrently
Copy link
Member

@ericsnowcurrently ericsnowcurrently commented Aug 7, 2018

(fixes #2245)

  • Title summarizes what is changing
  • Includes a news entry file (remember to thank yourself!)
  • Unit tests & code coverage are not adversely affected (within reason)
  • Works on all actively maintained versions of Python (e.g. Python 2.7 & the latest Python 3 release)
  • Works on Windows 10, macOS, and Linux (e.g. considered file system case-sensitivity)
  • Dependencies are pinned (e.g. "1.2.3", not "^1.2.3")
  • package-lock.json has been regenerated if dependencies have changed

}
public get pathVariableName() {
return this.isWindows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
}
public get virtualEnvBinName() {
return this.isWindows ? 'scripts' : 'bin';
}

// XXX Drop the following (in favor of osType).
public get isWindows(): boolean {

Choose a reason for hiding this comment

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

👌👌👌👌👌👌👌👏👏👏

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll do it in a separate PR.

}
public get isMac(): boolean {
return this._isMac;
public get osType(): OSType {

Choose a reason for hiding this comment

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

Why not just os() instead of osType?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@@ -9,6 +9,13 @@ export enum Architecture {
x86 = 2,
x64 = 3
}
export enum OSType {
Unsupported,

Choose a reason for hiding this comment

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

Unknown is better. This could be used on other contexts too.

Copy link
Member Author

Choose a reason for hiding this comment

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

good point

fixed


let distro = '';
let version = '';
const data = fs.readFileSync(filename, 'utf-8');

Choose a reason for hiding this comment

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

Please use IFileSystem
The logic in this class needs to be testable.

Choose a reason for hiding this comment

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

With exception handling

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed (wasn't trivial)

}
}

function linux_info_from_file(filename: string = LINUX_INFO_FILE): LinuxInfo {

Choose a reason for hiding this comment

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

Functions are verbs, hence should be named as such. That's how it is in js and .net world.
Please change to get Linux....
Also please do not use underscores in method names. User Pascal casing.

Choose a reason for hiding this comment

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

E.g. a better name would be getLinuxInformationFromFile

Try avoiding abbreviations.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@codecov
Copy link

codecov bot commented Aug 7, 2018

Codecov Report

Merging #2351 into master will increase coverage by 0.22%.
The diff coverage is 88.05%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2351      +/-   ##
==========================================
+ Coverage   75.38%   75.61%   +0.22%     
==========================================
  Files         309      310       +1     
  Lines       14331    14506     +175     
  Branches     2537     2567      +30     
==========================================
+ Hits        10804    10969     +165     
- Misses       3518     3529      +11     
+ Partials        9        8       -1
Flag Coverage Δ
#MacOS 74.39% <83.01%> (+0.19%) ⬆️
#Windows 74.52% <83.01%> (+0.22%) ⬆️
Impacted Files Coverage Δ
src/client/common/platform/types.ts 100% <100%> (ø) ⬆️
src/client/telemetry/constants.ts 100% <100%> (ø) ⬆️
src/client/common/platform/platformService.ts 100% <100%> (+10.52%) ⬆️
src/client/common/platform/osinfo.ts 82.65% <82.65%> (ø)
src/client/activation/activationService.ts 95.83% <93.54%> (-1.9%) ⬇️
src/client/common/utils.ts 74.68% <0%> (-1.64%) ⬇️
src/client/activation/languageServer.ts 25.68% <0%> (-0.41%) ⬇️
src/client/common/types.ts 100% <0%> (ø) ⬆️
...nt/unittests/common/services/testResultsService.ts 92.85% <0%> (ø) ⬆️
src/client/common/serviceRegistry.ts 100% <0%> (ø) ⬆️
... and 5 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 6707eaa...ab4e333. Read the comment docs.

const osType: OSType = values[0];
const osVer: string = values[1];
const engine: string = values[2];
test(`LS is ${engine === 'ls' ? '' : 'not '}supported (${osType} ${osVer})`, async () => {

Choose a reason for hiding this comment

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

Or you can:
const [osType, osVer, engine] = values
I'm certain that feel a little bit more pythonic too
(Please don't change, it's merely a suggestion).

const jedi = this.useJedi();
let jedi = this.useJedi();
if (!jedi && !isLSSupported(this.serviceContainer)) {
this.appShell.showWarningMessage('The Python Language Server is not supported on your platform.');

Choose a reason for hiding this comment

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

Choose a reason for hiding this comment

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

Actually, it would be error. OR we should tell user that we are switching to Jedi explicitly.

import { IConfigurationService, IDisposableRegistry, IOutputChannel, IPythonSettings } from '../common/types';
import { IServiceContainer } from '../ioc/types';
import { ExtensionActivators, IExtensionActivationService, IExtensionActivator } from './types';

const jediEnabledSetting: keyof IPythonSettings = 'jediEnabled';
const LS_MIN_OS_VERSIONS: Map<OSType, string> = new Map([
[OSType.OSX, '10.12.0'] // Sierra or higher

Choose a reason for hiding this comment

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

On MacOS you can simply check os.release() which gives you Darwin version and .NET supports Darwin 16+ (10.12+)

const platform = services.get<IPlatformService>(IPlatformService);
const minVer = LS_MIN_OS_VERSIONS[platform.osType];
if (minVer === undefined || minVer === null) {
return true;

Choose a reason for hiding this comment

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

Show something in the output that platform was not recognized? Or log telemetry?

const jedi = this.useJedi();
let jedi = this.useJedi();
if (!jedi && !isLSSupported(this.serviceContainer)) {
this.appShell.showWarningMessage('The Python Language Server is not supported on your platform.');

Choose a reason for hiding this comment

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

This also needs telemetry so we know how many platforms were not supported.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

activationService.dispose();
activator.verifyAll();
});
};
test('Activatory must be activated', async () => {

Choose a reason for hiding this comment

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

What is acivatory?

Copy link
Member Author

Choose a reason for hiding this comment

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

No idea. That was already there.

@ericsnowcurrently ericsnowcurrently force-pushed the fix-2245-ls-unsupported-os branch from a837ae2 to cbb3d2d Compare August 20, 2018 21:27
@ericsnowcurrently ericsnowcurrently changed the title [WIP] Ignore the language server if the platform is not supported. Ignore the language server if the platform is not supported. Aug 20, 2018
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 remove stubs file, we should use what we have or other libraries, also we need to be consistent in how we do things (writing tests, coding styles, etc).
Makes it easier for others as well, including those trying to contribute, use standard/popular libraries unless there's a very good reason not to.

* @memberof FileSystem
*/
public readFileSync(filePath: string): string {
return fs.readFileSync(filePath, 'utf8');

Choose a reason for hiding this comment

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

Please remove sync version of file io. Where possible we must use async code.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@inject(IFileSystem) filesystem?: IFileSystem
) {
if (info) {
this.os = info;

Choose a reason for hiding this comment

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

We have three ways to populate the os property, why is this? Why do we need to pass it as an argument? Why can't we always determine it using osinfo.
It's complicated and wrong (encapsulation) to have three ways to do the exact same thing!

We have more code paths to test as well.

Choose a reason for hiding this comment

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

It's not upto the calling classes to provide the is information. Completely defeats the purpose of having this class. This class should be responsible to determine/extract the os information.
Please fix this before merging.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed


export function getOSInfo(
readFile: (string) => string = (filename) => {
return fs.readFileSync(filename, 'utf8');

Choose a reason for hiding this comment

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

This function is not testable due to the use of fs!
You'll need to ensure you have physical files, makes it more difficult to test, these fall into system tests, which is unnecessary for such a simple function.

Copy link
Member Author

@ericsnowcurrently ericsnowcurrently Aug 21, 2018

Choose a reason for hiding this comment

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

I'm not sure I understand. In tests you pass in readFile. fs is only used as the default.

}

export class OSInfo {
constructor(

Choose a reason for hiding this comment

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

types.js should only contain interfaces/contracts, not implementations.
Please remove the classes from here.
Please fix this before merging

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

return new OSInfo(osType, arch, version);
}

// Inspired in part by: https://github.com/juju/os

Choose a reason for hiding this comment

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

Isn't there's an npm package we can use instead?
Reduces maintenance headaches for something that's very generic.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was trying to avoid adding a new dependency. :) I'll look for a suitable library.

Copy link
Member Author

Choose a reason for hiding this comment

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

found one

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

* }
*
* const s = new MyStub();
* mod.func = s.someFunc; // monkey-patch
Copy link

@DonJayamanne DonJayamanne Aug 21, 2018

Choose a reason for hiding this comment

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

What's wrong with typemocks that already allows you to create mocked classes, this is a reinvention of a wheel here.
Please remove before merging.
I'm a strong believer if using existing libraries, that are well tested, and it makes it easier for others to use as well. E.g. if we need to support async meetings, you'll need to change code in this stubs framework, i.e. slippery slope of maintaining code that's already supported by other libraries.

@ericsnowcurrently
Copy link
Member Author

I'm going to land the change with the stub left in. IMO, doing it with mocks instead is much harder to understand (and write). @DonJayamanne, we'll have a discussion about this when you get back. If we decide that mocks are the one true way then I'll switch this code to use mocks. :)

Copy link

@d3r3kk d3r3kk left a comment

Choose a reason for hiding this comment

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

Your solution looks fine to me, and I look forward to having the conversation re:stubs vs TypeMoq when @DonJayamanne returns.

One thing to consider, open an issue to discuss this type of change and label it as P0 for Sept milestone!

@ericsnowcurrently ericsnowcurrently dismissed DonJayamanne’s stale review August 22, 2018 22:24

Everything addressed except for stub concerns.

@ericsnowcurrently ericsnowcurrently merged commit d031657 into microsoft:master Aug 22, 2018
@ericsnowcurrently ericsnowcurrently deleted the fix-2245-ls-unsupported-os branch August 22, 2018 22:27
@lock lock bot locked as resolved and limited conversation to collaborators Jul 31, 2019
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.

Detect when language server will not run on a platform (e.g. macOS El Capitan)
4 participants