Skip to content

Commit e5fb3b2

Browse files
authored
Add display better error message when path to .Net runtime is incorrect (#35)
- closes #34
1 parent f1ae5c7 commit e5fb3b2

File tree

9 files changed

+612
-214
lines changed

9 files changed

+612
-214
lines changed

package-lock.json

Lines changed: 112 additions & 139 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ooxml-validator.ts

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@ import { spawnSync } from 'child_process';
22
import { createObjectCsvWriter } from 'csv-writer';
33
import { basename, dirname, extname, isAbsolute, join, normalize } from 'path';
44
import { TextEncoder } from 'util';
5-
import { Uri, ViewColumn, WebviewPanel, commands, extensions, window, workspace } from 'vscode';
5+
import { Uri, ViewColumn, WebviewPanel, commands, extensions } from 'vscode';
66
import { Header, IDotnetAcquireResult, IValidationError, ValidationError } from './models';
7-
8-
// wrapping methods to make stubbing for tests easier
9-
export const effEss = {
10-
createDirectory: workspace.fs.createDirectory,
11-
writeFile: workspace.fs.writeFile,
12-
};
7+
import { ExtensionUtilities, WindowUtilities, WorkspaceUtilities } from './utilities';
138

149
export default class OOXMLValidator {
1510
static createLogFile = async (validationErrors: ValidationError[], path: string): Promise<string | undefined> => {
@@ -22,8 +17,8 @@ export default class OOXMLValidator {
2217
}
2318

2419
if (isAbsolute(normalizedPath)) {
25-
await effEss.createDirectory(Uri.file(dirname(normalizedPath)));
26-
const overwriteLogFile: boolean | undefined = workspace.getConfiguration('ooxml').get('overwriteLogFile');
20+
await WorkspaceUtilities.createDirectory(dirname(normalizedPath));
21+
const overwriteLogFile: boolean | undefined = WorkspaceUtilities.getConfigurationValue<boolean>('ooxml', 'overwriteLogFile');
2722

2823
if (!overwriteLogFile) {
2924
normalizedPath = `${normalizedPath.substring(0, normalizedPath.length - ext.length)}.${new Date()
@@ -33,7 +28,7 @@ export default class OOXMLValidator {
3328

3429
if (ext === '.json') {
3530
const encoder = new TextEncoder();
36-
await effEss.writeFile(Uri.file(normalizedPath), encoder.encode(JSON.stringify(validationErrors, null, 2)));
31+
await WorkspaceUtilities.writeFile(normalizedPath, encoder.encode(JSON.stringify(validationErrors, null, 2)));
3732
} else {
3833
const csvWriter = createObjectCsvWriter({
3934
path: normalizedPath,
@@ -56,19 +51,27 @@ export default class OOXMLValidator {
5651

5752
return normalizedPath;
5853
} else {
59-
await window.showErrorMessage('OOXML Validator\nooxml.outPutFilePath must be an absolute path');
54+
await WindowUtilities.showError('OOXML Validator\nooxml.outPutFilePath must be an absolute path');
6055
}
6156
};
6257

63-
static getWebviewContent = (validationErrors?: ValidationError[], version?: string, fileName?: string, path?: string): string => {
58+
static getWebviewContent = (
59+
validationErrors?: ValidationError[],
60+
version?: string,
61+
fileName?: string,
62+
path?: string,
63+
): string => {
6464
if (validationErrors && validationErrors.length) {
6565
let list = '';
66-
validationErrors.forEach(err => {
66+
validationErrors.forEach((err) => {
6767
list += `<dl class="row">
6868
<dt class="col-sm-3">Id</dt>
6969
<dd class="col-sm-9">${err.Id}</dd>
7070
<dt class="col-sm-3">Description</dt>
71-
<dd class="col-sm-9">${err.Description?.replace(/</g, '&lt;')}</dd>
71+
<dd class="col-sm-9">${err.Description?.replace(
72+
/</g,
73+
'&lt;',
74+
)}</dd>
7275
<dt class="col-sm-3">XPath</dt>
7376
<dd class="col-sm-9">
7477
${err.XPath}
@@ -78,7 +81,9 @@ export default class OOXMLValidator {
7881
<dt class="col-sm-3">NamespacesDefinitions</dt>
7982
<dd class="col-sm-9">
8083
<ul>
81-
${err.NamespacesDefinitions?.map((n: string) => `<li>${n}</li>`).join('')}
84+
${err.NamespacesDefinitions?.map(
85+
(n: string) => `<li>${n}</li>`,
86+
).join('')}
8287
</ul>
8388
</dd>
8489
</dl>`;
@@ -107,36 +112,21 @@ export default class OOXMLValidator {
107112
<div class="container-fluid pt-3 ol-3">
108113
<div class="row pb-3">
109114
<div class="col">
110-
<h1>There Were ${validationErrors.length} Validation Errors Found</h1>
115+
<h1>There ${validationErrors.length === 1 ? 'was' : 'were'} ${
116+
validationErrors.length
117+
} Validation Error${validationErrors.length > 1 ? 's' : ''} Found</h1>
111118
<h2>Validating against ${version}</h2>
112-
${path
113-
? `<h3>A log of these errors was saved as "${path}"</h3>`
114-
: // eslint-disable-next-line max-len
115-
'<h3>No log of these errors was saved.</h3><h4>Set "ooxml.outPutFilePath" in settings.json to save a log (csv or json) of the errors</h4>'
116-
}
117-
</div>
118-
</div>
119-
<div class="row pb-3">
120-
<div class="col">
121-
<div class="btn-group-toggle"
122-
data-toggle="collapse"
123-
data-target="#collapseExample"
124-
aria-expanded="false"
125-
aria-controls="collapseExample"
126-
>
127-
<label class="btn btn-outline-secondary" id="error-btn">
128-
<input
129-
class="btn btn-outline-secondary"
130-
type="checkbox"
131-
checked
132-
/>
133-
</label>
134-
</div>
119+
${
120+
path
121+
? `<h3>A log of these errors was saved as "${path}"</h3>`
122+
: // eslint-disable-next-line max-len
123+
'<h3>No log of these errors was saved.</h3><h4>Set "ooxml.outPutFilePath" in settings.json to save a log (csv or json) of the errors</h4>'
124+
}
135125
</div>
136126
</div>
137127
<div class="row pb-3">
138128
<div class="col">
139-
<div class="collapse" id="collapseExample">
129+
<div>
140130
<div class="card card-body">
141131
${list}
142132
</div>
@@ -281,7 +271,7 @@ export default class OOXMLValidator {
281271
};
282272

283273
static validate = async (uri: Uri) => {
284-
const panel: WebviewPanel = window.createWebviewPanel('validateOOXML', 'OOXML Validate', ViewColumn.One, { enableScripts: true });
274+
const panel: WebviewPanel = WindowUtilities.createWebView('validateOOXML', 'OOXML Validate', ViewColumn.One, { enableScripts: true });
285275

286276
try {
287277
panel.webview.html = OOXMLValidator.getWebviewContent();
@@ -295,17 +285,31 @@ export default class OOXMLValidator {
295285
formatVersions.set('2021', 'Office2021');
296286
formatVersions.set('365', 'Microsoft365');
297287

298-
const configVersion: number | string | undefined = workspace.getConfiguration('ooxml').get('fileFormatVersion');
288+
const configVersion: number | undefined = WorkspaceUtilities.getConfigurationValue<number>('ooxml', 'fileFormatVersion');
299289
const versionStr = configVersion?.toString();
300290
const versions = [...formatVersions.keys()];
301291
// Default to the latest format version
302292
const version =
303293
versionStr && versions.includes(versionStr) ? formatVersions.get(versionStr) : [...formatVersions.values()].pop();
304-
305294
await commands.executeCommand('dotnet.showAcquisitionLog');
306295

307296
const requestingExtensionId = 'mikeebowen.ooxml-validator-vscode';
308-
let dotnetPath: string | undefined = workspace.getConfiguration('ooxml').get('dotNetPath');
297+
let dotnetPath: string | undefined = WorkspaceUtilities.getConfigurationValue<string>('ooxml', 'dotNetPath');
298+
299+
if (dotnetPath) {
300+
const dotnetPathIsValid = await ExtensionUtilities.isDotNetRuntime(dotnetPath);
301+
302+
if (!dotnetPathIsValid) {
303+
dotnetPath = undefined;
304+
305+
await WindowUtilities.showWarning(
306+
'OOXML Validator: The .NET path set in the settings is not valid.',
307+
// eslint-disable-next-line max-len
308+
'Using the .NET Install Tool for Extension Authors extension to acquire .NET Runtime.\nUpdate the ooxml.dotNetPath setting to the use a local runtime.',
309+
true,
310+
);
311+
}
312+
}
309313

310314
if (!dotnetPath) {
311315
const commandRes = await commands.executeCommand<IDotnetAcquireResult>('dotnet.acquire', {
@@ -315,7 +319,7 @@ export default class OOXMLValidator {
315319
dotnetPath = commandRes!.dotnetPath;
316320

317321
if (!dotnetPath) {
318-
throw new Error('Could not resolve the dotnet path!');
322+
throw new Error('Could not acquire .NET runtime.');
319323
}
320324
}
321325

@@ -335,7 +339,7 @@ export default class OOXMLValidator {
335339
const stderr = result?.stderr?.toString();
336340

337341
if (stderr?.length > 0) {
338-
window.showErrorMessage(`Failed to run OOXML Validator. The error was:\n${stderr}`, { modal: true });
342+
WindowUtilities.showError(`Failed to run OOXML Validator. The error was:\n${stderr}`, true);
339343
panel.dispose();
340344

341345
return;
@@ -346,7 +350,7 @@ export default class OOXMLValidator {
346350
let content: string;
347351

348352
if (validationErrors.length) {
349-
const path: string | undefined = workspace.getConfiguration('ooxml').get('outPutFilePath');
353+
const path: string | undefined = WorkspaceUtilities.getConfigurationValue<string>('ooxml', 'outPutFilePath');
350354
let pathToSavedFile: string | undefined;
351355

352356
if (path) {
@@ -375,7 +379,8 @@ export default class OOXMLValidator {
375379
});
376380

377381
panel?.dispose();
378-
await window.showErrorMessage(errMsg, { modal: true });
382+
383+
await WindowUtilities.showError(errMsg, true);
379384
}
380385
};
381386
}

0 commit comments

Comments
 (0)