Skip to content

Commit 66a7f1e

Browse files
committed
Fix test suite
1 parent dbccc60 commit 66a7f1e

File tree

2 files changed

+71
-44
lines changed

2 files changed

+71
-44
lines changed

src/hlsBinaries.ts

+65-38
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,11 @@ async function callAsync(
139139
* Downloads the latest haskell-language-server binaries via ghcup.
140140
* Returns null if it can't find any match.
141141
*/
142-
export async function downloadHaskellLanguageServer(context: ExtensionContext, logger: Logger, workingDir: string): Promise<string> {
142+
export async function downloadHaskellLanguageServer(
143+
context: ExtensionContext,
144+
logger: Logger,
145+
workingDir: string
146+
): Promise<string> {
143147
logger.info('Downloading haskell-language-server');
144148

145149
const storagePath: string = await getStoragePath(context);
@@ -150,21 +154,24 @@ export async function downloadHaskellLanguageServer(context: ExtensionContext, l
150154
}
151155

152156
const localWrapper = ['haskell-language-server-wrapper'].find(executableExists);
153-
const downloadedWrapper = path.join(
154-
storagePath,
155-
'.ghcup',
156-
'bin',
157-
`haskell-language-server-wrapper${exeExt}`
158-
);
157+
const downloadedWrapper = path.join(storagePath, '.ghcup', 'bin', `haskell-language-server-wrapper${exeExt}`);
159158
let wrapper: string | undefined;
160-
if (localWrapper) { // first try PATH
159+
if (localWrapper) {
160+
// first try PATH
161161
wrapper = localWrapper;
162-
} else if (executableExists(downloadedWrapper)) { // then try internal ghcup
162+
} else if (executableExists(downloadedWrapper)) {
163+
// then try internal ghcup
163164
wrapper = downloadedWrapper;
164165
}
165166

166167
const ghcup = path.join(storagePath, 'ghcup');
167168
const updateBehaviour = workspace.getConfiguration('haskell').get('updateBehavior') as UpdateBehaviour;
169+
const [installable_hls, latest_hls_version, project_ghc] = await getLatestSuitableHLS(
170+
context,
171+
logger,
172+
workingDir,
173+
wrapper
174+
);
168175

169176
// check if we need to update HLS
170177
if (wrapper == null) {
@@ -184,40 +191,21 @@ export async function downloadHaskellLanguageServer(context: ExtensionContext, l
184191
}
185192
await callAsync(
186193
ghcup,
187-
['--no-verbose', 'install', 'hls', 'latest'],
194+
['--no-verbose', 'install', 'hls', installable_hls],
188195
storagePath,
189196
logger,
190-
`Installing latest HLS`,
197+
`Installing HLS ${installable_hls}`,
191198
true,
192199
{ GHCUP_INSTALL_BASE_PREFIX: storagePath }
193200
);
194-
await callAsync(
195-
ghcup,
196-
['--no-verbose', 'set', 'hls', 'latest'],
197-
storagePath,
198-
logger,
199-
undefined,
200-
false,
201-
{ GHCUP_INSTALL_BASE_PREFIX: storagePath }
202-
);
201+
await callAsync(ghcup, ['--no-verbose', 'set', 'hls', installable_hls], storagePath, logger, undefined, false, {
202+
GHCUP_INSTALL_BASE_PREFIX: storagePath,
203+
});
203204
return downloadedWrapper;
204205
} else {
205-
206206
// version of active hls wrapper
207207
const set_version = await callAsync(wrapper, ['--numeric-version'], storagePath, logger);
208208

209-
// get latest hls version
210-
const hls_versions = await callAsync(ghcup, ['--no-verbose', 'list', '-t', 'hls', '-c', 'available', '-r'], storagePath, logger, undefined, false, { GHCUP_INSTALL_BASE_PREFIX: storagePath });
211-
const latest_hls_version = hls_versions.split(/\r?\n/).pop()!.split(' ')[1];
212-
213-
// get project GHC version
214-
// TODO: we may run this function twice on startup (e.g. in extension.ts)
215-
const project_ghc = await getProjectGHCVersion(wrapper, workingDir, logger);
216-
217-
// get installable HLS that supports the project GHC version (this might not be the most recent)
218-
const latest_metadata_hls = (project_ghc != null) ? await getLatestHLSforGHC(context, storagePath, project_ghc, logger) : null;
219-
const installable_hls = (latest_metadata_hls != null) ? latest_metadata_hls : latest_hls_version;
220-
221209
const downgrade: boolean = comparePVP(latest_hls_version, installable_hls) > 0;
222210

223211
const projectHlsWrapper = path.join(
@@ -240,9 +228,9 @@ export async function downloadHaskellLanguageServer(context: ExtensionContext, l
240228
let promptMessage: string;
241229
if (downgrade) {
242230
promptMessage = `A different (lower) version of the haskell-language-server is required to support ${project_ghc}, would you like to upgrade now?`;
243-
244231
} else {
245-
promptMessage = 'A new version of the haskell-language-server is available, would you like to upgrade now?';
232+
promptMessage =
233+
'A new version of the haskell-language-server is available, would you like to upgrade now?';
246234
}
247235

248236
const decision = await window.showInformationMessage(promptMessage, 'Download', 'Nevermind');
@@ -251,7 +239,11 @@ export async function downloadHaskellLanguageServer(context: ExtensionContext, l
251239
}
252240
} else {
253241
if (downgrade && need_install) {
254-
const decision = await window.showInformationMessage(`Cannot install the latest HLS version ${latest_hls_version}, because it does not support GHC ${project_ghc}. Installing HLS ${installable_hls} instead?`, 'Continue', "Abort");
242+
const decision = await window.showInformationMessage(
243+
`Cannot install the latest HLS version ${latest_hls_version}, because it does not support GHC ${project_ghc}. Installing HLS ${installable_hls} instead?`,
244+
'Continue',
245+
'Abort'
246+
);
255247
if (decision !== 'Continue') {
256248
return wrapper;
257249
}
@@ -264,8 +256,7 @@ export async function downloadHaskellLanguageServer(context: ExtensionContext, l
264256
const symHLSPath = path.join(storagePath, 'hls', installable_hls);
265257
await callAsync(
266258
ghcup,
267-
[ '--no-verbose', 'run', '--hls', installable_hls
268-
, '-b', symHLSPath, '-i'],
259+
['--no-verbose', 'run', '--hls', installable_hls, '-b', symHLSPath, '-i'],
269260
storagePath,
270261
logger,
271262
need_install ? `Installing HLS ${installable_hls}` : undefined,
@@ -278,6 +269,42 @@ export async function downloadHaskellLanguageServer(context: ExtensionContext, l
278269
}
279270
}
280271

272+
async function getLatestSuitableHLS(
273+
context: ExtensionContext,
274+
logger: Logger,
275+
workingDir: string,
276+
wrapper?: string
277+
): Promise<[string, string, string | null]> {
278+
const storagePath: string = await getStoragePath(context);
279+
const ghcup = path.join(storagePath, 'ghcup');
280+
281+
// get latest hls version
282+
const hls_versions = await callAsync(
283+
ghcup,
284+
['--no-verbose', 'list', '-t', 'hls', '-c', 'available', '-r'],
285+
storagePath,
286+
logger,
287+
undefined,
288+
false,
289+
{ GHCUP_INSTALL_BASE_PREFIX: storagePath }
290+
);
291+
const latest_hls_version = hls_versions.split(/\r?\n/).pop()!.split(' ')[1];
292+
293+
// get project GHC version
294+
// TODO: we may run this function twice on startup (e.g. in extension.ts)
295+
const project_ghc =
296+
wrapper == undefined
297+
? await callAsync('ghc', ['--numeric-version'], storagePath, logger, undefined, false)
298+
: await getProjectGHCVersion(wrapper, workingDir, logger);
299+
300+
// get installable HLS that supports the project GHC version (this might not be the most recent)
301+
const latest_metadata_hls =
302+
project_ghc != null ? await getLatestHLSforGHC(context, storagePath, project_ghc, logger) : null;
303+
const installable_hls = latest_metadata_hls != null ? latest_metadata_hls : latest_hls_version;
304+
305+
return [installable_hls, latest_hls_version, project_ghc];
306+
}
307+
281308
// also serves as sanity check
282309
export async function validateHLSToolchain(
283310
wrapper: string,

test/suite/extension.test.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ suite('Extension Test Suite', () => {
9696
const pred = (uri: vscode.Uri) => !['download', 'gz', 'zip'].includes(path.extname(uri.fsPath));
9797
const exeExt = os.platform.toString() === 'win32' ? '.exe' : '';
9898
// Setting up watchers before actual tests start, to ensure we will got the created event
99-
filesCreated.set('wrapper', existsWorkspaceFile(`bin/haskell-language-server-wrapper*${exeExt}`, pred));
100-
filesCreated.set('server', existsWorkspaceFile(`bin/haskell-language-server-[1-9]*${exeExt}`, pred));
99+
filesCreated.set('wrapper', existsWorkspaceFile(`bin/.ghcup/bin/haskell-language-server-wrapper*${exeExt}`, pred));
100+
filesCreated.set('server', existsWorkspaceFile(`bin/.ghcup/bin/haskell-language-server-[1-9]*${exeExt}`, pred));
101101
filesCreated.set('log', existsWorkspaceFile('hls.log'));
102102
filesCreated.set('cache', existsWorkspaceFile('cache-test'));
103103
});
@@ -120,13 +120,13 @@ suite('Extension Test Suite', () => {
120120
await vscode.workspace.openTextDocument(getWorkspaceFile('Main.hs'));
121121
console.log('Testing wrapper');
122122
assert.ok(
123-
await withTimeout(30, filesCreated.get('wrapper')!),
124-
'The wrapper executable was not downloaded in 30 seconds'
123+
await withTimeout(120, filesCreated.get('wrapper')!),
124+
'The wrapper executable was not downloaded in 120 seconds'
125125
);
126126
console.log('Testing server');
127127
assert.ok(
128-
await withTimeout(60, filesCreated.get('server')!),
129-
'The server executable was not downloaded in 60 seconds'
128+
await withTimeout(120, filesCreated.get('server')!),
129+
'The server executable was not downloaded in 120 seconds'
130130
);
131131
});
132132

0 commit comments

Comments
 (0)