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

feat: add always start with language-server positional arg, add logging args if given [HEAD-693] #374

Merged
merged 5 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Snyk Security - Code and Open Source Dependencies Changelog

## [1.21.6]
## [1.23.0]
- add `language-server` as first positional argument to language server start
- enable setting of log level in language server via SNYK_LOG_LEVEL
- enable setting of debug level in language server via `-d` or `--debug`

## [1.22.0]

### Added

Expand Down
20 changes: 18 additions & 2 deletions src/snyk/common/languageServer/languageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
import { LanguageClientMiddleware } from './middleware';
import { InitializationOptions, LanguageServerSettings } from './settings';
import { CodeIssueData, IacIssueData, OssIssueData, Scan } from './types';
import * as fs from 'fs';

Check warning on line 27 in src/snyk/common/languageServer/languageServer.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

'fs' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 27 in src/snyk/common/languageServer/languageServer.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

'fs' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 27 in src/snyk/common/languageServer/languageServer.ts

View workflow job for this annotation

GitHub Actions / Build and Test (windows-latest)

'fs' is defined but never used. Allowed unused vars must match /^_/u

export interface ILanguageServer {
start(): Promise<void>;

stop(): Promise<void>;

showOutputChannel(): void;

cliReady$: ReplaySubject<string>;
Expand Down Expand Up @@ -77,11 +80,24 @@

const lsBinaryPath = LsExecutable.getPath(this.configuration.getSnykLanguageServerPath());

this.logger.info(`Snyk Language Server path: ${lsBinaryPath}`);
// log level is set to info by default
let logLevel = 'info';
const additionalCliParameters = this.configuration.getAdditionalCliParameters();
if (
additionalCliParameters != null &&
additionalCliParameters.length > 0 &&
(additionalCliParameters.includes('-d') || additionalCliParameters.includes('--debug'))
) {
logLevel = 'debug';
}
logLevel = process.env.SNYK_LOG_LEVEL ?? logLevel;

const args = ['language-server', '-l', logLevel];
this.logger.info(`Snyk Language Server - path: ${lsBinaryPath}`);
this.logger.info(`Snyk Language Server - args: ${args}`);
const serverOptions: ServerOptions = {
command: lsBinaryPath,
args: ['-l', 'info'],
args: args,
options: {
env: processEnv,
},
Expand Down
67 changes: 61 additions & 6 deletions src/test/unit/common/languageServer/languageServer.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import assert, { deepStrictEqual, strictEqual } from 'assert';
/* eslint-disable @typescript-eslint/no-empty-function */
import assert, { deepStrictEqual, fail, strictEqual } from 'assert';
import { ReplaySubject } from 'rxjs';
import sinon from 'sinon';
import { v4 } from 'uuid';
Expand All @@ -24,24 +24,34 @@ suite('Language Server', () => {
let configurationMock: IConfiguration;
let languageServer: LanguageServer;
let downloadServiceMock: DownloadService;
const path = 'testPath';
const logger = {
info(_msg: string) {},
warn(_msg: string) {},
log(_msg: string) {},
error(msg: string) {
fail(msg);
},
} as unknown as LoggerMock;

setup(() => {
configurationMock = {
getInsecure(): boolean {
return true;
},
getCliPath(): string | undefined {
return 'testPath';
return path;
},
getToken(): Promise<string | undefined> {
return Promise.resolve('testToken');
},
shouldReportEvents: true,
shouldReportErrors: true,
getSnykLanguageServerPath(): string {
return 'testPath';
return path;
},
getAdditionalCliParameters() {
return '--all-projects';
return '--all-projects -d';
},
isAutomaticDependencyManagementEnabled() {
return true;
Expand Down Expand Up @@ -76,6 +86,49 @@ suite('Language Server', () => {
sinon.restore();
});

test('LanguageServer starts with correct args', async () => {
const lca = sinon.spy({
create(
_id: string,
_name: string,
serverOptions: ServerOptions,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_clientOptions: LanguageClientOptions,
): LanguageClient {
return {
start(): Promise<void> {
assert.strictEqual('args' in serverOptions ? serverOptions?.args?.[0] : '', 'language-server');
assert.strictEqual('args' in serverOptions ? serverOptions?.args?.[1] : '', '-l');
assert.strictEqual('args' in serverOptions ? serverOptions?.args?.[2] : '', 'debug');
return Promise.resolve();
},
onNotification(): void {
return;
},
onReady(): Promise<void> {
return Promise.resolve();
},
} as unknown as LanguageClient;
},
});

languageServer = new LanguageServer(
user,
configurationMock,
lca as unknown as ILanguageClientAdapter,
stubWorkspaceConfiguration('snyk.loglevel', 'trace'),
windowMock,
authServiceMock,
logger,
downloadServiceMock,
);
downloadServiceMock.downloadReady$.next();

await languageServer.start();
sinon.assert.called(lca.create);
sinon.verify();
});

test('LanguageServer adds proxy settings to env of started binary', async () => {
const expectedProxy = 'http://localhost:8080';
const lca = sinon.spy({
Expand All @@ -90,9 +143,11 @@ suite('Language Server', () => {
assert.strictEqual(id, 'Snyk LS');
assert.strictEqual(name, 'Snyk Language Server');
assert.strictEqual(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
'options' in serverOptions ? serverOptions?.options?.env?.http_proxy : undefined,
expectedProxy,
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
assert.strictEqual(clientOptions.initializationOptions.token, 'testToken');
return Promise.resolve();
},
Expand Down Expand Up @@ -158,7 +213,7 @@ suite('Language Server', () => {
automaticAuthentication: 'false',
endpoint: undefined,
organization: undefined,
additionalParams: '--all-projects',
additionalParams: '--all-projects -d',
manageBinariesAutomatically: 'true',
deviceId: user.anonymousId,
filterSeverity: { critical: true, high: true, medium: true, low: true },
Expand Down
Loading