|
1 | 1 | import * as yaml from 'js-yaml'; |
2 | 2 | import * as path from 'path'; |
3 | 3 | import * as vscode from 'vscode'; |
| 4 | +import Ajv from 'ajv'; |
| 5 | + |
| 6 | +import * as scgSchema from '../../schemas/scg_config.schema.json'; |
| 7 | + |
| 8 | +const ajv = new Ajv(); |
| 9 | +const validate_scg = ajv.compile<ScgConfigSchema>(scgSchema); |
4 | 10 |
|
5 | 11 | export interface ScgConfigSchema { |
6 | 12 | outputfile?: string; |
@@ -153,89 +159,32 @@ export async function readScgConfig(filePath: string): Promise<ScgConfigSchema | |
153 | 159 | const uri = vscode.Uri.file(filePath); |
154 | 160 | const document = await vscode.workspace.openTextDocument(uri); |
155 | 161 | const fileContents = document.getText(); |
156 | | - const data = yaml.load(fileContents) as ScgConfigSchema; |
157 | | - if (!validateScgConfig(data)) { |
158 | | - return undefined; |
| 162 | + const data = yaml.load(fileContents); |
| 163 | + |
| 164 | + if (validate_scg(data)) { |
| 165 | + return data; |
159 | 166 | } |
160 | | - return data; |
| 167 | + let errorMessage = `Error validating ${filePath} against the SCG schema:\n`; |
| 168 | + errorMessage += validate_scg.errors.map(error => `SCG config validation error at ${error.instancePath}: ${error.message}`).join('\n'); |
| 169 | + vscode.window.showErrorMessage(errorMessage); |
| 170 | + return undefined; |
161 | 171 | } catch { |
162 | 172 | return undefined; |
163 | 173 | } |
164 | 174 | } |
165 | 175 |
|
166 | | -export function validateScgConfig(data: ScgConfigSchema): boolean { |
167 | | - if (!data.templatepath || typeof data.templatepath !== 'string') return false; |
168 | | - if (data.adjustspacing && typeof data.adjustspacing !== 'boolean') return false; |
169 | | - if (data.verifycontent && typeof data.verifycontent !== 'boolean') return false; |
170 | | - |
171 | | - // Validate optional fields |
172 | | - if (data.outputfile && typeof data.outputfile !== 'string') return false; |
173 | | - |
174 | | - // Validate counters |
175 | | - if (data.counters) { |
176 | | - for (const counter of data.counters) { |
177 | | - if (typeof counter.name !== 'string' || typeof counter.value !== 'number') return false; |
178 | | - } |
179 | | - } |
180 | | - |
181 | | - // Validate sources |
182 | | - for (const source of data.sources) { |
183 | | - if (typeof source.filename !== 'string' || typeof source.id !== 'string') return false; |
184 | | - if (source.sheet && typeof source.sheet !== 'string') return false; |
185 | | - if (source.delimiter && typeof source.delimiter !== 'string') return false; |
186 | | - } |
187 | | - |
188 | | - // Validate layout |
189 | | - for (const layout of data.layout) { |
190 | | - if (typeof layout.name !== 'string') return false; |
191 | | - if (layout.source && typeof layout.source !== 'string') return false; |
192 | | - if (layout.include && typeof layout.include !== 'object') return false; |
193 | | - } |
194 | | - |
195 | | - return true; |
196 | | -} |
197 | | - |
198 | 176 | export async function isScgConfig(filePath: string): Promise<boolean> { |
199 | 177 | try { |
200 | 178 | const uri = vscode.Uri.file(filePath); |
201 | 179 | const document = await vscode.workspace.openTextDocument(uri); |
202 | 180 | const fileContents = document.getText(); |
203 | | - const data = yaml.load(fileContents) as ScgConfigSchema; |
204 | | - return validateScgConfig(data); |
| 181 | + const data = yaml.load(fileContents); |
| 182 | + return validate_scg(data); |
205 | 183 | } catch { |
206 | 184 | return false; |
207 | 185 | } |
208 | 186 | } |
209 | 187 |
|
210 | | -export async function findScgConfigFiles(): Promise<vscode.Uri[]> { |
211 | | - try { |
212 | | - const activeEditor = vscode.window.activeTextEditor; |
213 | | - if (!activeEditor) { |
214 | | - return []; |
215 | | - } |
216 | | - let currentFolder = vscode.Uri.file(activeEditor.document.uri.fsPath).with({ path: vscode.Uri.file(activeEditor.document.uri.fsPath).path.replace(/\/[^/]+$/, '') }); |
217 | | - const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath; |
218 | | - |
219 | | - while (currentFolder.fsPath.startsWith(workspaceFolder || '') && currentFolder.fsPath !== workspaceFolder) { |
220 | | - const files = await vscode.workspace.findFiles(new vscode.RelativePattern(currentFolder, '*.yaml')); |
221 | | - const scgConfigFiles: vscode.Uri[] = []; |
222 | | - for (const file of files) { |
223 | | - if (await isScgConfig(file.fsPath)) { |
224 | | - scgConfigFiles.push(file); |
225 | | - } |
226 | | - } |
227 | | - if (scgConfigFiles.length > 0) { |
228 | | - return scgConfigFiles; |
229 | | - } |
230 | | - currentFolder = vscode.Uri.file(currentFolder.fsPath).with({ path: vscode.Uri.file(currentFolder.fsPath).path.replace(/\/[^/]+$/, '') }); |
231 | | - } |
232 | | - return []; |
233 | | - } catch (error) { |
234 | | - console.error('Error finding SCG config files:', error); |
235 | | - return []; |
236 | | - } |
237 | | -} |
238 | | - |
239 | 188 |
|
240 | 189 | export class ScgSource { |
241 | 190 | id: string; |
|
0 commit comments