@@ -2,14 +2,9 @@ import { spawnSync } from 'child_process';
22import { createObjectCsvWriter } from 'csv-writer' ;
33import { basename , dirname , extname , isAbsolute , join , normalize } from 'path' ;
44import { TextEncoder } from 'util' ;
5- import { Uri , ViewColumn , WebviewPanel , commands , extensions , window , workspace } from 'vscode' ;
5+ import { Uri , ViewColumn , WebviewPanel , commands , extensions } from 'vscode' ;
66import { 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
149export 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, '<' ) } </dd>
71+ <dd class="col-sm-9">${ err . Description ?. replace (
72+ / < / g,
73+ '<' ,
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