From 24cb0f91d7b2f49b1394b444c98f44c002b38880 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 10:52:31 +0100 Subject: [PATCH 01/13] Upgrade glob library --- server/package.json | 2 +- server/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/package.json b/server/package.json index 47b1612ca..43974e6b3 100644 --- a/server/package.json +++ b/server/package.json @@ -18,7 +18,7 @@ "node": "*" }, "dependencies": { - "glob": "^7.1.2", + "glob": "^7.1.6", "request": "^2.83.0", "request-promise-native": "^1.0.5", "turndown": "^4.0.2", diff --git a/server/yarn.lock b/server/yarn.lock index 143797c8f..7f7071657 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -328,10 +328,10 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== +glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" From 8f1f2e4eabb07a9fcc3b378091bd6ecd0cd07e12 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 10:53:07 +0100 Subject: [PATCH 02/13] Refactor glob implementation --- server/src/analyser.ts | 60 ++++++++++++++++++------------------------ server/src/util/fs.ts | 22 ++++++++++++++++ 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/server/src/analyser.ts b/server/src/analyser.ts index b0005aa7d..97b094796 100644 --- a/server/src/analyser.ts +++ b/server/src/analyser.ts @@ -1,6 +1,4 @@ import * as fs from 'fs' -import * as glob from 'glob' -import * as Path from 'path' import * as request from 'request-promise-native' import * as URI from 'urijs' import * as LSP from 'vscode-languageserver' @@ -8,6 +6,7 @@ import * as Parser from 'web-tree-sitter' import { uniqueBasedOnHash } from './util/array' import { flattenArray, flattenObjectValues } from './util/flatten' +import { getFilePaths } from './util/fs' import * as TreeSitterUtil from './util/tree-sitter' type Kinds = { [type: string]: LSP.SymbolKind } @@ -28,9 +27,9 @@ export default class Analyzer { * root path. * * If the rootPath is provided it will initialize all *.sh files it can find - * anywhere on that path. + * anywhere on that path. This non-exhaustive glob is used to preload the parser. */ - public static fromRoot({ + public static async fromRoot({ connection, rootPath, parser, @@ -39,39 +38,30 @@ export default class Analyzer { rootPath: string | null parser: Parser }): Promise { - // This happens if the users opens a single bash script without having the - // 'window' associated with a specific project. - if (!rootPath) { - return Promise.resolve(new Analyzer(parser)) - } + const analyzer = new Analyzer(parser) + + const lookupStartTime = Date.now() + + if (rootPath) { + // NOTE: An alternative would be to preload all files and analyze their + // shebang (this would only be needed if we supported cross file referencing). + const filePaths = await getFilePaths({ globPattern: '**/*.sh', rootPath }) + + filePaths.forEach(filePath => { + const uri = `file://${filePath}` + connection.console.log(`Analyzing ${uri}`) + + const fileContent = fs.readFileSync(filePath, 'utf8') - return new Promise((resolve, reject) => { - glob('**/*.sh', { cwd: rootPath }, (err, paths) => { - if (err != null) { - reject(err) - } else { - const analyzer = new Analyzer(parser) - paths.forEach(p => { - const absolute = Path.join(rootPath, p) - // only analyze files, glob pattern may match directories - if (fs.existsSync(absolute) && fs.lstatSync(absolute).isFile()) { - const uri = `file://${absolute}` - connection.console.log(`Analyzing ${uri}`) - analyzer.analyze( - uri, - LSP.TextDocument.create( - uri, - 'shell', - 1, - fs.readFileSync(absolute, 'utf8'), - ), - ) - } - }) - resolve(analyzer) - } + analyzer.analyze(uri, LSP.TextDocument.create(uri, 'shell', 1, fileContent)) }) - }) + } + + connection.console.log( + `Analyzer finished after ${(Date.now() - lookupStartTime) / 1000} seconds`, + ) + + return analyzer } private parser: Parser diff --git a/server/src/util/fs.ts b/server/src/util/fs.ts index b6165815b..ce82d41c2 100644 --- a/server/src/util/fs.ts +++ b/server/src/util/fs.ts @@ -1,4 +1,5 @@ import * as Fs from 'fs' +import * as glob from 'glob' import * as Os from 'os' export function getStats(path: string): Promise { @@ -20,3 +21,24 @@ export function untildify(pathWithTilde: string): string { ? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) : pathWithTilde } + +export async function getFilePaths({ + globPattern, + rootPath, +}: { + globPattern: string + rootPath: string +}): Promise { + return new Promise((resolve, reject) => { + glob(globPattern, { cwd: rootPath, nodir: true, absolute: true }, function( + err, + files, + ) { + if (err) { + return reject(err) + } + + resolve(files) + }) + }) +} From fff83c2e859903d90a5d02f15e498a1790a0dee8 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 11:07:14 +0100 Subject: [PATCH 03/13] Add test for analyzer.fromRoot --- server/src/__tests__/analyzer.test.ts | 50 ++++++++++++++++++++++++++- testing/fixtures.ts | 4 +-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/server/src/__tests__/analyzer.test.ts b/server/src/__tests__/analyzer.test.ts index 2a03612bf..cb0de41fa 100644 --- a/server/src/__tests__/analyzer.test.ts +++ b/server/src/__tests__/analyzer.test.ts @@ -1,4 +1,4 @@ -import FIXTURES from '../../../testing/fixtures' +import FIXTURES, { FIXTURE_FOLDER } from '../../../testing/fixtures' import Analyzer from '../analyser' import { initializeParser } from '../parser' @@ -97,3 +97,51 @@ describe('findSymbolCompletions', () => { expect(analyzer.findSymbolCompletions(CURRENT_URI)).toMatchSnapshot() }) }) + +describe('fromRoot', () => { + it('initializes an analyzer from a root', async () => { + const parser = await initializeParser() + + jest.spyOn(Date, 'now').mockImplementation(() => 0) + + const connection: any = { + console: { + log: jest.fn(), + }, + } + + const newAnalyzer = await Analyzer.fromRoot({ + connection, + rootPath: FIXTURE_FOLDER, + parser, + }) + + expect(newAnalyzer).toBeDefined() + + expect(connection.console.log).toHaveBeenCalledTimes(5) + expect(connection.console.log).toHaveBeenNthCalledWith( + 1, + 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/install.sh', + ) + + expect(connection.console.log).toHaveBeenNthCalledWith( + 2, + 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/issue101.sh', + ) + + expect(connection.console.log).toHaveBeenNthCalledWith( + 3, + 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/missing-node.sh', + ) + + expect(connection.console.log).toHaveBeenNthCalledWith( + 4, + 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/parse-problems.sh', + ) + + expect(connection.console.log).toHaveBeenNthCalledWith( + 5, + 'Analyzer finished after 0 seconds', + ) + }) +}) diff --git a/testing/fixtures.ts b/testing/fixtures.ts index c0dcfbf74..1c3624d40 100644 --- a/testing/fixtures.ts +++ b/testing/fixtures.ts @@ -2,14 +2,14 @@ import * as fs from 'fs' import * as path from 'path' import * as LSP from 'vscode-languageserver' -const base = path.join(__dirname, './fixtures/') +export const FIXTURE_FOLDER = path.join(__dirname, './fixtures/') function getFixture(filename: string) { return LSP.TextDocument.create( 'foo', 'bar', 0, - fs.readFileSync(path.join(base, filename), 'utf8'), + fs.readFileSync(path.join(FIXTURE_FOLDER, filename), 'utf8'), ) } From 4e90873f0e42b3336ed5bd5cd8ac99c4fc891826 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 11:07:47 +0100 Subject: [PATCH 04/13] Add fixture demonstrating that .inc files works --- testing/fixtures/extension.inc | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 testing/fixtures/extension.inc diff --git a/testing/fixtures/extension.inc b/testing/fixtures/extension.inc new file mode 100644 index 000000000..81cf153fe --- /dev/null +++ b/testing/fixtures/extension.inc @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "It works, but is not parsed initially" From 155294dd1c773b97b26aea9a7d2d953a4cde0f15 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 11:14:27 +0100 Subject: [PATCH 05/13] Add fixture documenting jump to definition --- testing/fixtures/extension.inc | 6 ++++++ testing/fixtures/sourcing.sh | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 testing/fixtures/sourcing.sh diff --git a/testing/fixtures/extension.inc b/testing/fixtures/extension.inc index 81cf153fe..b927ec700 100644 --- a/testing/fixtures/extension.inc +++ b/testing/fixtures/extension.inc @@ -1,3 +1,9 @@ #!/bin/sh echo "It works, but is not parsed initially" + +RED=`tput setaf 1` +GREEN=`tput setaf 2` +BLUE=`tput setaf 4` +BOLD=`tput bold` +RESET=`tput sgr0` diff --git a/testing/fixtures/sourcing.sh b/testing/fixtures/sourcing.sh new file mode 100644 index 000000000..7ff024422 --- /dev/null +++ b/testing/fixtures/sourcing.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +source ./extension.inc + +echo $RED 'Hello in red!' From 1a5729e06204e1c429fa5a038acb63b71b1cd914 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 11:18:06 +0100 Subject: [PATCH 06/13] Add fixture documenting how .sh are always parsed --- testing/fixtures/not-a-shell-script.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 testing/fixtures/not-a-shell-script.sh diff --git a/testing/fixtures/not-a-shell-script.sh b/testing/fixtures/not-a-shell-script.sh new file mode 100644 index 000000000..40e97856f --- /dev/null +++ b/testing/fixtures/not-a-shell-script.sh @@ -0,0 +1,4 @@ +if this is not a shell script, then it should not be parsed + +echo "Or is it?" + From 63cd76cd83ff8b45f81afaec0fdbd8fcf783d42c Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 11:28:44 +0100 Subject: [PATCH 07/13] Add another non shell script fixture --- testing/fixtures/not-a-shell-script2.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 testing/fixtures/not-a-shell-script2.sh diff --git a/testing/fixtures/not-a-shell-script2.sh b/testing/fixtures/not-a-shell-script2.sh new file mode 100644 index 000000000..d76b97283 --- /dev/null +++ b/testing/fixtures/not-a-shell-script2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env python2.7 +# set -x + +def func(): + print 'hello world' From 52bd910fd307da05d8d8fe2fa43d3af990d79da3 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 12:28:03 +0100 Subject: [PATCH 08/13] Pre-parse files with .sh|.inc|.bash|.command extensions Previously only .sh files where parsed. This also makes the glob configurable. --- server/src/__tests__/analyzer.test.ts | 18 ++++++++---------- server/src/__tests__/config.test.ts | 16 ++++++++++++++++ server/src/analyser.ts | 8 +++++++- server/src/config.ts | 7 +++++++ vscode-client/package.json | 7 ++++++- vscode-client/src/extension.ts | 3 +++ 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/server/src/__tests__/analyzer.test.ts b/server/src/__tests__/analyzer.test.ts index cb0de41fa..2c1f8804c 100644 --- a/server/src/__tests__/analyzer.test.ts +++ b/server/src/__tests__/analyzer.test.ts @@ -118,29 +118,27 @@ describe('fromRoot', () => { expect(newAnalyzer).toBeDefined() - expect(connection.console.log).toHaveBeenCalledTimes(5) + const FIXTURE_FILES_MATCHING_GLOB = 8 + const LOG_LINES = FIXTURE_FILES_MATCHING_GLOB + 2 + + expect(connection.console.log).toHaveBeenCalledTimes(LOG_LINES) expect(connection.console.log).toHaveBeenNthCalledWith( 1, - 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/install.sh', + expect.stringContaining('Analyzing files matching'), ) expect(connection.console.log).toHaveBeenNthCalledWith( 2, - 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/issue101.sh', + 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/extension.inc', ) expect(connection.console.log).toHaveBeenNthCalledWith( 3, - 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/missing-node.sh', - ) - - expect(connection.console.log).toHaveBeenNthCalledWith( - 4, - 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/parse-problems.sh', + 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/install.sh', ) expect(connection.console.log).toHaveBeenNthCalledWith( - 5, + LOG_LINES, 'Analyzer finished after 0 seconds', ) }) diff --git a/server/src/__tests__/config.test.ts b/server/src/__tests__/config.test.ts index bbf7390e8..dd30649bc 100644 --- a/server/src/__tests__/config.test.ts +++ b/server/src/__tests__/config.test.ts @@ -16,6 +16,22 @@ describe('getExplainshellEndpoint', () => { }) }) +describe('getGlobPattern', () => { + it('default to a basic glob', () => { + process.env = {} + const result = config.getGlobPattern() + expect(result).toEqual('**/*@(.sh|.inc|.bash|.command)') + }) + + it('parses environment variable', () => { + process.env = { + GLOB_PATTERN: '*.*', + } + const result = config.getGlobPattern() + expect(result).toEqual('*.*') + }) +}) + describe('highlightParsingError', () => { it('default to true', () => { process.env = {} diff --git a/server/src/analyser.ts b/server/src/analyser.ts index 97b094796..7ff2a1155 100644 --- a/server/src/analyser.ts +++ b/server/src/analyser.ts @@ -4,6 +4,7 @@ import * as URI from 'urijs' import * as LSP from 'vscode-languageserver' import * as Parser from 'web-tree-sitter' +import { getGlobPattern } from './config' import { uniqueBasedOnHash } from './util/array' import { flattenArray, flattenObjectValues } from './util/flatten' import { getFilePaths } from './util/fs' @@ -43,9 +44,14 @@ export default class Analyzer { const lookupStartTime = Date.now() if (rootPath) { + const globPattern = getGlobPattern() + connection.console.log( + `Analyzing files matching glob "${globPattern}" inside ${rootPath}`, + ) + // NOTE: An alternative would be to preload all files and analyze their // shebang (this would only be needed if we supported cross file referencing). - const filePaths = await getFilePaths({ globPattern: '**/*.sh', rootPath }) + const filePaths = await getFilePaths({ globPattern, rootPath }) filePaths.forEach(filePath => { const uri = `file://${filePath}` diff --git a/server/src/config.ts b/server/src/config.ts index 719553a51..216afd75f 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -3,6 +3,13 @@ export function getExplainshellEndpoint(): string | null { return typeof EXPLAINSHELL_ENDPOINT !== 'undefined' ? EXPLAINSHELL_ENDPOINT : null } +export function getGlobPattern(): string { + const { GLOB_PATTERN } = process.env + return typeof GLOB_PATTERN === 'string' + ? GLOB_PATTERN + : '**/*@(.sh|.inc|.bash|.command)' +} + export function getHighlightParsingError(): boolean { const { HIGHLIGHT_PARSING_ERRORS } = process.env return typeof HIGHLIGHT_PARSING_ERRORS !== 'undefined' diff --git a/vscode-client/package.json b/vscode-client/package.json index 4ff9a03c9..6b1f494c2 100644 --- a/vscode-client/package.json +++ b/vscode-client/package.json @@ -31,10 +31,15 @@ "type": "object", "title": "Bash IDE configuration", "properties": { + "bashIde.globPattern": { + "type": "string", + "default": "**/*@(.sh|.inc|.bash|.command)", + "description": "Glob pattern for finding and parsing shell script files." + }, "bashIde.highlightParsingErrors": { "type": "boolean", "default": true, - "description": "If enabled parsing errors will be highlighted as 'problems' " + "description": "If enabled parsing errors will be highlighted as problems." }, "bashIde.explainshellEndpoint": { "type": "string", diff --git a/vscode-client/src/extension.ts b/vscode-client/src/extension.ts index 1c504a814..0e649ee91 100644 --- a/vscode-client/src/extension.ts +++ b/vscode-client/src/extension.ts @@ -13,6 +13,8 @@ export async function activate(context: ExtensionContext) { .getConfiguration('bashIde') .get('explainshellEndpoint', '') + const globPattern = workspace.getConfiguration('bashIde').get('globPattern', false) + const highlightParsingErrors = workspace .getConfiguration('bashIde') .get('highlightParsingErrors', false) @@ -20,6 +22,7 @@ export async function activate(context: ExtensionContext) { const env: any = { ...process.env, EXPLAINSHELL_ENDPOINT: explainshellEndpoint, + GLOB_PATTERN: globPattern, HIGHLIGHT_PARSING_ERRORS: highlightParsingErrors, } From 2eba2529bcfd9960f3aa48f1e5ebaba65d6f0816 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 12:47:06 +0100 Subject: [PATCH 09/13] Simplify configuration parsing --- server/src/__tests__/config.test.ts | 18 +++++++++++++++++- server/src/config.ts | 10 +++++++--- vscode-client/src/extension.ts | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/server/src/__tests__/config.test.ts b/server/src/__tests__/config.test.ts index dd30649bc..755a188bf 100644 --- a/server/src/__tests__/config.test.ts +++ b/server/src/__tests__/config.test.ts @@ -7,6 +7,14 @@ describe('getExplainshellEndpoint', () => { expect(result).toBeNull() }) + it('default to null in case of an empty string', () => { + process.env = { + EXPLAINSHELL_ENDPOINT: '', + } + const result = config.getExplainshellEndpoint() + expect(result).toBeNull() + }) + it('parses environment variable', () => { process.env = { EXPLAINSHELL_ENDPOINT: 'localhost:8080', @@ -20,7 +28,15 @@ describe('getGlobPattern', () => { it('default to a basic glob', () => { process.env = {} const result = config.getGlobPattern() - expect(result).toEqual('**/*@(.sh|.inc|.bash|.command)') + expect(result).toEqual(config.DEFAULT_GLOB_PATTERN) + }) + + it('default to a basic glob in case of an empty string', () => { + process.env = { + GLOB_PATTERN: '', + } + const result = config.getGlobPattern() + expect(result).toEqual(config.DEFAULT_GLOB_PATTERN) }) it('parses environment variable', () => { diff --git a/server/src/config.ts b/server/src/config.ts index 216afd75f..712f8022e 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -1,13 +1,17 @@ +export const DEFAULT_GLOB_PATTERN = '**/*@(.sh|.inc|.bash|.command)' + export function getExplainshellEndpoint(): string | null { const { EXPLAINSHELL_ENDPOINT } = process.env - return typeof EXPLAINSHELL_ENDPOINT !== 'undefined' ? EXPLAINSHELL_ENDPOINT : null + return typeof EXPLAINSHELL_ENDPOINT === 'string' && EXPLAINSHELL_ENDPOINT.trim() !== '' + ? EXPLAINSHELL_ENDPOINT + : null } export function getGlobPattern(): string { const { GLOB_PATTERN } = process.env - return typeof GLOB_PATTERN === 'string' + return typeof GLOB_PATTERN === 'string' && GLOB_PATTERN.trim() !== '' ? GLOB_PATTERN - : '**/*@(.sh|.inc|.bash|.command)' + : DEFAULT_GLOB_PATTERN } export function getHighlightParsingError(): boolean { diff --git a/vscode-client/src/extension.ts b/vscode-client/src/extension.ts index 0e649ee91..ab8b9d99b 100644 --- a/vscode-client/src/extension.ts +++ b/vscode-client/src/extension.ts @@ -13,7 +13,7 @@ export async function activate(context: ExtensionContext) { .getConfiguration('bashIde') .get('explainshellEndpoint', '') - const globPattern = workspace.getConfiguration('bashIde').get('globPattern', false) + const globPattern = workspace.getConfiguration('bashIde').get('globPattern', '') const highlightParsingErrors = workspace .getConfiguration('bashIde') From b2d7f71a75f997e766698b927eb307e1b6066973 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 13:41:39 +0100 Subject: [PATCH 10/13] Remove test for file names (not deterministic) --- server/src/__tests__/analyzer.test.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/server/src/__tests__/analyzer.test.ts b/server/src/__tests__/analyzer.test.ts index 2c1f8804c..448fdcef2 100644 --- a/server/src/__tests__/analyzer.test.ts +++ b/server/src/__tests__/analyzer.test.ts @@ -127,16 +127,6 @@ describe('fromRoot', () => { expect.stringContaining('Analyzing files matching'), ) - expect(connection.console.log).toHaveBeenNthCalledWith( - 2, - 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/extension.inc', - ) - - expect(connection.console.log).toHaveBeenNthCalledWith( - 3, - 'Analyzing file:///Users/kenneth/git/bash-language-server/testing/fixtures/install.sh', - ) - expect(connection.console.log).toHaveBeenNthCalledWith( LOG_LINES, 'Analyzer finished after 0 seconds', From f5c2efc630b345492c4d5ee98f75e089693fe6d8 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 15:07:46 +0100 Subject: [PATCH 11/13] Update fixtures --- server/src/analyser.ts | 2 +- testing/fixtures/extension | 3 +++ testing/fixtures/extension.inc | 2 -- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 testing/fixtures/extension diff --git a/server/src/analyser.ts b/server/src/analyser.ts index 7ff2a1155..20c1bc724 100644 --- a/server/src/analyser.ts +++ b/server/src/analyser.ts @@ -27,7 +27,7 @@ export default class Analyzer { * Initialize the Analyzer based on a connection to the client and an optional * root path. * - * If the rootPath is provided it will initialize all *.sh files it can find + * If the rootPath is provided it will initialize all shell files it can find * anywhere on that path. This non-exhaustive glob is used to preload the parser. */ public static async fromRoot({ diff --git a/testing/fixtures/extension b/testing/fixtures/extension new file mode 100644 index 000000000..81cf153fe --- /dev/null +++ b/testing/fixtures/extension @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "It works, but is not parsed initially" diff --git a/testing/fixtures/extension.inc b/testing/fixtures/extension.inc index b927ec700..40c13ab44 100644 --- a/testing/fixtures/extension.inc +++ b/testing/fixtures/extension.inc @@ -1,7 +1,5 @@ #!/bin/sh -echo "It works, but is not parsed initially" - RED=`tput setaf 1` GREEN=`tput setaf 2` BLUE=`tput setaf 4` From 6b995164a742a2422643ab914f878270fc05cb0e Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 16:39:39 +0100 Subject: [PATCH 12/13] Add log line with glob timing --- server/src/__tests__/analyzer.test.ts | 2 +- server/src/analyser.ts | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/server/src/__tests__/analyzer.test.ts b/server/src/__tests__/analyzer.test.ts index 448fdcef2..a9f6638fa 100644 --- a/server/src/__tests__/analyzer.test.ts +++ b/server/src/__tests__/analyzer.test.ts @@ -119,7 +119,7 @@ describe('fromRoot', () => { expect(newAnalyzer).toBeDefined() const FIXTURE_FILES_MATCHING_GLOB = 8 - const LOG_LINES = FIXTURE_FILES_MATCHING_GLOB + 2 + const LOG_LINES = FIXTURE_FILES_MATCHING_GLOB + 3 expect(connection.console.log).toHaveBeenCalledTimes(LOG_LINES) expect(connection.console.log).toHaveBeenNthCalledWith( diff --git a/server/src/analyser.ts b/server/src/analyser.ts index 20c1bc724..cefd1b56a 100644 --- a/server/src/analyser.ts +++ b/server/src/analyser.ts @@ -41,31 +41,33 @@ export default class Analyzer { }): Promise { const analyzer = new Analyzer(parser) - const lookupStartTime = Date.now() - if (rootPath) { const globPattern = getGlobPattern() connection.console.log( `Analyzing files matching glob "${globPattern}" inside ${rootPath}`, ) + const lookupStartTime = Date.now() + const getTimePassed = (): string => + `${(Date.now() - lookupStartTime) / 1000} seconds` + // NOTE: An alternative would be to preload all files and analyze their - // shebang (this would only be needed if we supported cross file referencing). + // shebang or mimetype, but it would be fairly expensive. const filePaths = await getFilePaths({ globPattern, rootPath }) + connection.console.log( + `Glob resolved with ${filePaths.length} files after ${getTimePassed()}`, + ) + filePaths.forEach(filePath => { const uri = `file://${filePath}` connection.console.log(`Analyzing ${uri}`) - const fileContent = fs.readFileSync(filePath, 'utf8') - analyzer.analyze(uri, LSP.TextDocument.create(uri, 'shell', 1, fileContent)) }) - } - connection.console.log( - `Analyzer finished after ${(Date.now() - lookupStartTime) / 1000} seconds`, - ) + connection.console.log(`Analyzer finished after ${getTimePassed()}`) + } return analyzer } From e06d158f8fb1b6f4fcb674cd1e94365cc46aa975 Mon Sep 17 00:00:00 2001 From: skovhus Date: Mon, 2 Mar 2020 16:43:41 +0100 Subject: [PATCH 13/13] Bump server version --- server/CHANGELOG.md | 5 +++++ server/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/CHANGELOG.md b/server/CHANGELOG.md index 4b979c236..7ef04f8d1 100644 --- a/server/CHANGELOG.md +++ b/server/CHANGELOG.md @@ -1,5 +1,10 @@ # Bash Language Server +## 1.8.0 + +* Extend file glob used for pre-analyzing files from `**/*.sh` to `**/*@(.sh|.inc|.bash|.command)` +* Make file glob configurable with `GLOB_PATTERN` environment variable + ## 1.7.0 * Add PATH tilde expansion diff --git a/server/package.json b/server/package.json index 43974e6b3..ad949166f 100644 --- a/server/package.json +++ b/server/package.json @@ -3,7 +3,7 @@ "description": "A language server for Bash", "author": "Mads Hartmann", "license": "MIT", - "version": "1.7.0", + "version": "1.8.0", "publisher": "mads-hartmann", "main": "./out/server.js", "typings": "./out/server.d.ts",