Skip to content

Commit

Permalink
feat: add always start with language-server positional arg, add log…
Browse files Browse the repository at this point in the history
…ging args if given [HEAD-693] (#374)

* feat: add detection for standalone/cli-embedded based on size, add logging args if given `-d` or env var

- SNYK_LOG_DEVEL overrules all log level settings now
- `-d` or `--debug` in additional parameters now puts language server in debug mode

Signed-off-by: Bastian Doetsch <[email protected]>

* fix: make test method sync'ed

Signed-off-by: Bastian Doetsch <[email protected]>

* fix: tests

Signed-off-by: Bastian Doetsch <[email protected]>

* chore: remove unnecessary check for binary size

Signed-off-by: Bastian Doetsch <[email protected]>

* docs: update CHANGELOG.md

Signed-off-by: Bastian Doetsch <[email protected]>

---------

Signed-off-by: Bastian Doetsch <[email protected]>
  • Loading branch information
bastiandoetsch authored Sep 11, 2023
1 parent 0e053e7 commit ffd080f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 9 deletions.
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 { LsExecutable } from './lsExecutable';
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 / 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 / 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 / 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 @@ export class LanguageServer implements ILanguageServer {

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

0 comments on commit ffd080f

Please sign in to comment.