Skip to content

Commit 4a33ecc

Browse files
committed
Added YamlValidatorRedHat
1 parent 684901c commit 4a33ecc

File tree

4 files changed

+227
-66
lines changed

4 files changed

+227
-66
lines changed

docs/Project-templates.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Templates are used to create projects and add `launch.json` and `tasks.json` fil
2020

2121
Templates are listed in load order in the extension. For example, if a template of type `user` has the same identifier `id` of the template with type `system`, then the template of type `user` will be ignored because the template of type `system` is already loaded.
2222

23-
If the system template does not pass the check, it will be automatically deleted and replaced with a valid one. If the system template is deleted, it will also be automatically restored. System templates are automatically updated when you run an extension from [Github devdotnetorg/vscode-extension-dotnet-fastiot/tree/master/templates/system](https://github.com/devdotnetorg/vscode-extension-dotnet-fastiot/tree/ master/templates/system). Further, everything will be discussed using the example of the template [dotnet-console-runtime-info](/templates/system/dotnet-console-runtime-info).
23+
If the system template does not pass the check, it will be automatically deleted and replaced with a valid one. If the system template is deleted, it will also be automatically restored. System templates are automatically updated when you run an extension from [Github devdotnetorg/vscode-extension-dotnet-fastiot/tree/master/templates/system](https://github.com/devdotnetorg/vscode-extension-dotnet-fastiot/tree/master/templates/system). Further, everything will be discussed using the example of the template [dotnet-console-runtime-info](/templates/system/dotnet-console-runtime-info).
2424

2525
## Template structure
2626

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,9 @@
11
# for https://github.com/redhat-developer/vscode-yaml
2-
id:
3-
type: string
4-
required: true
5-
platform:
6-
- type: string
7-
required: true
8-
version:
9-
type: string
10-
required: true
11-
releaseDate:
12-
type: string
13-
required: true
14-
forVersionExt:
15-
type: string
16-
required: true
17-
author:
18-
type: string
19-
required: true
20-
emailAuthor:
21-
type: string
22-
required: true
23-
license:
24-
type: string
25-
required: true
26-
label:
27-
type: string
28-
required: true
29-
detail:
30-
type: string
31-
required: true
32-
description:
33-
type: string
34-
required: true
35-
language:
36-
type: string
37-
required: true
38-
endDeviceArchitecture:
39-
- type: string
40-
required: true
41-
tags:
42-
- type: string
43-
required: true
44-
dependOnPackages:
45-
- type: string
46-
required: true
47-
typeProj:
48-
type: string
49-
required: true
50-
projName:
51-
type: string
52-
required: true
53-
mainFileProj:
54-
type: string
55-
required: true
56-
mainFileProjLabel:
57-
type: string
58-
required: true
59-
filesToProcess:
60-
- type: string
61-
required: true
62-
fileNameReplacement:
63-
- type: string
64-
required: true
2+
title: ".NET FastIoT. Project Template"
3+
type: object
4+
properties:
5+
id:
6+
type: string
7+
description: "Entity unique identifier"
8+
required:
9+
- id
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import * as vscode from 'vscode';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import { IotResult,StatusResult } from '../IotResult';
5+
import { IYamlValidator } from './IYamlValidator';
6+
import { IoTHelper } from '../Helper/IoTHelper';
7+
8+
export class YamlRedHatServiceSingleton {
9+
private static instance: YamlRedHatServiceSingleton;
10+
//
11+
private readonly _identifierExtension="redhat.vscode-yaml";
12+
private readonly _SCHEMA = "myschema";
13+
private readonly _timeout = 60; // 30 sec
14+
private _yamlExtension:vscode.Extension<any> | undefined;
15+
private _yamlExtensionAPI:any;
16+
private _schemas:Map<string,string>= new Map<string,string>();
17+
private _currentYamlFile:vscode.Uri=vscode.Uri.file("c://non");
18+
private _validationErrors:Array<string>=[];
19+
private _responseReceivedFlag=false;
20+
/**
21+
* Конструктор Одиночки всегда должен быть скрытым, чтобы предотвратить
22+
* создание объекта через оператор new.
23+
*/
24+
private constructor() { }
25+
26+
/**
27+
* Статический метод, управляющий доступом к экземпляру одиночки.
28+
*
29+
* Эта реализация позволяет вам расширять класс Одиночки, сохраняя повсюду
30+
* только один экземпляр каждого подкласса.
31+
*/
32+
public static getInstance(): YamlRedHatServiceSingleton {
33+
if (!YamlRedHatServiceSingleton.instance) {
34+
YamlRedHatServiceSingleton.instance = new YamlRedHatServiceSingleton();
35+
}
36+
return YamlRedHatServiceSingleton.instance;
37+
}
38+
39+
private async InstallExtension(): Promise<IotResult> {
40+
let result:IotResult;
41+
let msg:string;
42+
try {
43+
msg=`You need to install the Red Hat's YAML ("${this._identifierExtension}") extension ` +
44+
`for .NET FastIoT to work. The installation will now complete. Please wait 2-3 minutes.`;
45+
vscode.window.showWarningMessage(msg);
46+
//StatusBar
47+
let statusBarBackground= vscode.window.createStatusBarItem(
48+
vscode.StatusBarAlignment.Right, 1000);
49+
msg=`Install Red Hat's YAML extension`;
50+
statusBarBackground.text=`$(loading~spin) ${msg}`;
51+
statusBarBackground.tooltip=msg;
52+
//Install
53+
await vscode.commands.executeCommand(
54+
`workbench.extensions.installExtension`,
55+
`${this._identifierExtension}`
56+
);
57+
//
58+
statusBarBackground.hide();
59+
statusBarBackground.dispose();
60+
//repeat
61+
this._yamlExtension = vscode.extensions.getExtension(this._identifierExtension);
62+
if(this._yamlExtension) {
63+
msg=`Red Hat's extension successfully installed`;
64+
vscode.window.showInformationMessage(msg);
65+
result= new IotResult(StatusResult.Ok, msg);
66+
}else {
67+
msg=`Red Hat's YAML extension failed to install`;
68+
vscode.window.showErrorMessage(msg);
69+
result= new IotResult(StatusResult.Error, msg);
70+
}
71+
} catch (err: any){
72+
//result
73+
msg=`Red Hat's YAML extension failed to install`;
74+
vscode.window.showErrorMessage(msg);
75+
result= new IotResult(StatusResult.Error, msg);
76+
}
77+
return Promise.resolve(result);
78+
}
79+
80+
private onRequestSchemaURI(resource: string): string | undefined {
81+
if (resource.endsWith('.yaml')) {
82+
const filename = path.parse(resource).base;
83+
//ex: "myschema://schema/template.fastiot"
84+
return `${this._SCHEMA}://schema/${filename}`;
85+
}
86+
return undefined;
87+
}
88+
89+
private onRequestSchemaContent(schemaUri: string): string | undefined {
90+
const parsedUri = vscode.Uri.parse(schemaUri);
91+
if (parsedUri.scheme !== this._SCHEMA) {
92+
return undefined;
93+
}
94+
if (!parsedUri.path || !parsedUri.path.startsWith('/')) {
95+
return undefined;
96+
}
97+
//get schema
98+
const schema = this._schemas.get(schemaUri);
99+
//ex: "file:///d:/Anton/GitHub/vscode-extension-dotnet-fastiot/schemas/template.fastiot.schema.yaml"
100+
return schema;
101+
}
102+
103+
/**
104+
* redhat.vscode-yaml extension activation
105+
*/
106+
public async Activate(): Promise<IotResult> {
107+
//check
108+
if(this._yamlExtension && this._yamlExtension.isActive && this._yamlExtensionAPI) {
109+
//ok
110+
return Promise.resolve(new IotResult(StatusResult.Ok, "Red Hat's YAML extension is active"));
111+
}
112+
let result:IotResult;
113+
let msg:string;
114+
try {
115+
this._yamlExtension = vscode.extensions.getExtension(this._identifierExtension);
116+
if(!this._yamlExtension) {
117+
//need install
118+
result=await this.InstallExtension();
119+
if(result.Status==StatusResult.Error) return Promise.resolve(result);
120+
}
121+
//activate
122+
this._yamlExtensionAPI = await this._yamlExtension?.activate();
123+
//register
124+
this._yamlExtensionAPI.registerContributor(this._SCHEMA, this.onRequestSchemaURI, this.onRequestSchemaContent);
125+
//Diagnostics
126+
vscode.languages.onDidChangeDiagnostics(e => {
127+
e.uris.forEach(fileUri => {
128+
if(this._currentYamlFile==fileUri) {
129+
let diagnostics = vscode.languages.getDiagnostics(fileUri); // returns an array
130+
this._validationErrors=[];
131+
diagnostics.forEach(item => {
132+
this._validationErrors.push(item.message);
133+
});
134+
//
135+
this._responseReceivedFlag=true;
136+
//close file
137+
this.closeFileIfOpen(fileUri);
138+
}
139+
});
140+
});
141+
//next
142+
result= new IotResult(StatusResult.Ok, "Red Hat's YAML extension is active");
143+
} catch (err: any){
144+
//result
145+
const errorMsg="Red Hat's YAML extension is not active";
146+
result = new IotResult(StatusResult.Error,errorMsg,err);
147+
}
148+
return Promise.resolve(result);
149+
}
150+
151+
private AddSchema(schemaFilePath:string) {
152+
//template.fastiot.schema.yaml
153+
const filename = path.parse(schemaFilePath).base;
154+
let key = filename.substring(0,filename.length-12);
155+
//ex: "myschema://schema/template.fastiot"
156+
key=`${this._SCHEMA}://schema/${key}`;
157+
//exist
158+
if(this._schemas.has(key)) return;
159+
//add
160+
this._schemas.set(key,schemaFilePath);
161+
}
162+
163+
public async ValidateSchema (yamlFilePath:string, schemaFilePath:string):Promise<IotResult> {
164+
let result:IotResult;
165+
try {
166+
//Add schema
167+
this.AddSchema(schemaFilePath);
168+
//for response handler
169+
this._currentYamlFile=vscode.Uri.file(yamlFilePath);
170+
//adding a file to processing
171+
this._responseReceivedFlag=false;
172+
let ymldoc = await vscode.workspace.openTextDocument(vscode.Uri.file(yamlFilePath));
173+
//waiting response
174+
for (let i = 0; i < this._timeout; i++) {
175+
IoTHelper.Sleep(500);
176+
if(this._responseReceivedFlag) i=this._timeout;
177+
}
178+
//response
179+
if(this._responseReceivedFlag) {
180+
//ok
181+
const msg=`Response received from Red Hat's YAML extension`;
182+
result = new IotResult(StatusResult.Error,msg);
183+
if(this._validationErrors.length>0) {
184+
result.returnObject=this._validationErrors;
185+
}
186+
}else {
187+
//no response received
188+
const errorMsg=`No response received from Red Hat's YAML extension. ValidateSchema pathFileYml = ${yamlFilePath}, schemaFileName = ${schemaFilePath}`;
189+
result = new IotResult(StatusResult.Error,errorMsg);
190+
}
191+
} catch (err: any){
192+
//result
193+
const errorMsg=`Red Hat's YAML extension error ValidateSchema pathFileYml = ${yamlFilePath}, schemaFileName = ${schemaFilePath}`;
194+
result = new IotResult(StatusResult.Error,errorMsg,err);
195+
}
196+
return Promise.resolve(result);
197+
}
198+
199+
private async closeFileIfOpen(file:vscode.Uri) : Promise<void> {
200+
const tabs: vscode.Tab[] = vscode.window.tabGroups.all.map(tg => tg.tabs).flat();
201+
const index = tabs.findIndex(tab => tab.input instanceof vscode.TabInputText && tab.input.uri.path === file.path);
202+
if (index !== -1) {
203+
await vscode.window.tabGroups.close(tabs[index]);
204+
}
205+
}
206+
}
207+
208+
209+

src/Validator/YamlValidatorRedHat.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as fs from 'fs';
33
import * as path from 'path';
44
import { IotResult,StatusResult } from '../IotResult';
55
import { IYamlValidator } from './IYamlValidator';
6+
import { YamlRedHatServiceSingleton } from './YamlRedHatServiceSingleton';
67

78
export class YamlValidatorRedHat implements IYamlValidator {
89
private readonly _schemasFolderPath: string;
@@ -11,12 +12,17 @@ export class YamlValidatorRedHat implements IYamlValidator {
1112
this._schemasFolderPath=schemasFolderPath;
1213
}
1314

14-
public ValidateSchema (yamlFilePath:string, schemaFileName:string):IotResult
15+
public async ValidateSchema(yamlFilePath:string, schemaFileName:string):Promise<IotResult>
1516
{
1617
let result:IotResult;
1718
let validationErrors:Array<string>=[];
1819
let msg="";
1920
try {
21+
const instanceExtension = YamlRedHatServiceSingleton.getInstance();
22+
result=await instanceExtension.Activate();
23+
if(result.Status==StatusResult.Error)
24+
return Promise.resolve(result);
25+
2026
//source - https://www.npmjs.com/package/yaml-schema-validator-fork
2127
const validateSchema = require('yaml-schema-validator-fork');
2228
// validate a yml file
@@ -44,7 +50,8 @@ export class YamlValidatorRedHat implements IYamlValidator {
4450
validationErrors.push(result.toString());
4551
}
4652
result.returnObject=validationErrors;
47-
return result;
53+
54+
return Promise.resolve(result);
4855
}
4956
}
5057

0 commit comments

Comments
 (0)