Skip to content

Commit 57665d3

Browse files
committed
Fix YamlValidatorRedHat
1 parent 4a33ecc commit 57665d3

File tree

8 files changed

+101
-93
lines changed

8 files changed

+101
-93
lines changed

schemas/template.fastiot.schema.yaml renamed to schemas/template.fastiot.schema.redhat.vscode-yaml.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@ properties:
55
id:
66
type: string
77
description: "Entity unique identifier"
8+
id2:
9+
type: string
10+
description: "Id2 Entity unique identifier"
811
required:
912
- id
13+
- id2

schemas/template.schema.yaml renamed to schemas/template.fastiot.schema.validator-fork.yaml

File renamed without changes.

src/Entity/EntityBaseAttribute.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
22
import * as fs from 'fs';
33
import * as path from 'path';
44
import YAML from 'yaml';
5-
import { YamlValidatorRedHat } from '../Validator/YamlValidatorRedHat';
5+
import { YamlValidatorFork } from '../Validator/YamlValidatorFork';
66
import { IYamlValidator } from '../Validator/IYamlValidator';
77

88
export class EntityBaseAttribute {
@@ -64,7 +64,7 @@ export class EntityBaseAttribute {
6464
if(!result) false;
6565
result=this.PostCheckAfterParse(yamlFilePath);
6666
//
67-
return result;
67+
return result;
6868
}
6969

7070
private ParseBaseAttribute(yamlFilePath:string):boolean{
@@ -147,7 +147,7 @@ export class EntityBaseAttribute {
147147
return;
148148
}
149149
//YamlValidator
150-
let yamlValidator:IYamlValidator=new YamlValidatorRedHat(this._pathFolderSchema);
150+
let yamlValidator:IYamlValidator=new YamlValidatorFork(this._pathFolderSchema);
151151
let result = yamlValidator.ValidateSchema(yamlFilePath,this._fileNameSchemaRootYaml);
152152
const validationErrors=<Array<string>>result.returnObject;
153153
this._validationErrors = validationErrors.slice();

src/IotDevice.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export class IotDevice extends BaseTreeItem {
139139
this.Information.collapsibleState=vscode.TreeItemCollapsibleState.Expanded;
140140
this.PackagesLinux.collapsibleState=vscode.TreeItemCollapsibleState.Expanded;
141141
//
142-
return Promise.resolve(result);
142+
return Promise.resolve(result);
143143
}
144144

145145
private AddidDeviceInChildsInformation():void

src/Templates/IotTemplate.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ export class IotTemplate extends EntityBase<IotTemplateAttribute> {
4747
constructor(pathFolderSchema: string
4848
){
4949
super("template","templates",IotTemplateAttribute,
50-
pathFolderSchema,"template.fastiot.schema.yaml","template.fastiot.files.schema.json");
50+
pathFolderSchema,"template.fastiot.schema.validator-fork.yaml","template.fastiot.files.schema.json");
5151
}
5252

5353
public Init(type:EntityType,yamlFilePath:string,recoverySourcePath?:string)
5454
{
5555
super.Init(type,yamlFilePath,recoverySourcePath);
56+
//
5657
if(!this.IsValid) return;
5758
//Attributes
5859
const isValidAttributes = this.Attributes.Init(yamlFilePath);

src/Validator/YamlRedHatServiceSingleton.ts

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,31 @@ import * as path from 'path';
44
import { IotResult,StatusResult } from '../IotResult';
55
import { IYamlValidator } from './IYamlValidator';
66
import { IoTHelper } from '../Helper/IoTHelper';
7+
import YAML from 'yaml';
78

89
export class YamlRedHatServiceSingleton {
910
private static instance: YamlRedHatServiceSingleton;
1011
//
1112
private readonly _identifierExtension="redhat.vscode-yaml";
12-
private readonly _SCHEMA = "myschema";
1313
private readonly _timeout = 60; // 30 sec
14+
private readonly _SCHEMA = "myschema";
1415
private _yamlExtension:vscode.Extension<any> | undefined;
1516
private _yamlExtensionAPI:any;
1617
private _schemas:Map<string,string>= new Map<string,string>();
1718
private _currentYamlFile:vscode.Uri=vscode.Uri.file("c://non");
1819
private _validationErrors:Array<string>=[];
1920
private _responseReceivedFlag=false;
20-
/**
21-
* Конструктор Одиночки всегда должен быть скрытым, чтобы предотвратить
22-
* создание объекта через оператор new.
23-
*/
21+
2422
private constructor() { }
2523

26-
/**
27-
* Статический метод, управляющий доступом к экземпляру одиночки.
28-
*
29-
* Эта реализация позволяет вам расширять класс Одиночки, сохраняя повсюду
30-
* только один экземпляр каждого подкласса.
31-
*/
3224
public static getInstance(): YamlRedHatServiceSingleton {
3325
if (!YamlRedHatServiceSingleton.instance) {
3426
YamlRedHatServiceSingleton.instance = new YamlRedHatServiceSingleton();
3527
}
3628
return YamlRedHatServiceSingleton.instance;
3729
}
3830

39-
private async InstallExtension(): Promise<IotResult> {
31+
private async InstallExtensionAsync(): Promise<IotResult> {
4032
let result:IotResult;
4133
let msg:string;
4234
try {
@@ -47,13 +39,16 @@ export class YamlRedHatServiceSingleton {
4739
let statusBarBackground= vscode.window.createStatusBarItem(
4840
vscode.StatusBarAlignment.Right, 1000);
4941
msg=`Install Red Hat's YAML extension`;
42+
vscode.window.showWarningMessage(msg);
5043
statusBarBackground.text=`$(loading~spin) ${msg}`;
5144
statusBarBackground.tooltip=msg;
45+
statusBarBackground.show();
5246
//Install
5347
await vscode.commands.executeCommand(
5448
`workbench.extensions.installExtension`,
5549
`${this._identifierExtension}`
5650
);
51+
await vscode.commands.executeCommand("workbench.action.reloadWindow");
5752
//
5853
statusBarBackground.hide();
5954
statusBarBackground.dispose();
@@ -72,60 +67,67 @@ export class YamlRedHatServiceSingleton {
7267
//result
7368
msg=`Red Hat's YAML extension failed to install`;
7469
vscode.window.showErrorMessage(msg);
75-
result= new IotResult(StatusResult.Error, msg);
70+
result= new IotResult(StatusResult.Error, msg,err);
7671
}
7772
return Promise.resolve(result);
7873
}
7974

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-
10375
/**
10476
* redhat.vscode-yaml extension activation
10577
*/
106-
public async Activate(): Promise<IotResult> {
78+
public async ActivateAsync(): Promise<IotResult> {
79+
let result:IotResult;
10780
//check
10881
if(this._yamlExtension && this._yamlExtension.isActive && this._yamlExtensionAPI) {
10982
//ok
110-
return Promise.resolve(new IotResult(StatusResult.Ok, "Red Hat's YAML extension is active"));
83+
result=new IotResult(StatusResult.Ok, "Red Hat's YAML extension is active");
84+
return Promise.resolve(result);
11185
}
112-
let result:IotResult;
113-
let msg:string;
11486
try {
11587
this._yamlExtension = vscode.extensions.getExtension(this._identifierExtension);
11688
if(!this._yamlExtension) {
11789
//need install
118-
result=await this.InstallExtension();
90+
result=await this.InstallExtensionAsync();
11991
if(result.Status==StatusResult.Error) return Promise.resolve(result);
12092
}
12193
//activate
12294
this._yamlExtensionAPI = await this._yamlExtension?.activate();
95+
//func
96+
const onRequestSchemaURI = (resource: string): string | undefined => {
97+
if (resource.endsWith('.fastiot.yaml')) {
98+
const filename = path.parse(resource).base;
99+
//ex: "myschema://schema/template.fastiot"
100+
const schema=`${this._SCHEMA}://schema/${filename}`;
101+
return schema;
102+
}
103+
return undefined;
104+
};
105+
106+
const onRequestSchemaContent = (schemaUri: string): string | undefined => {
107+
//ex: template.fastiot.yaml
108+
const parsedUri = vscode.Uri.parse(schemaUri);
109+
if (parsedUri.scheme !== this._SCHEMA) {
110+
return undefined;
111+
}
112+
if (!parsedUri.path || !parsedUri.path.startsWith('/')) {
113+
return undefined;
114+
}
115+
if (parsedUri.path.length<5) {
116+
return undefined;
117+
}
118+
//get schema
119+
schemaUri=parsedUri.path.substring(1,parsedUri.path.length-5);
120+
const file = this._schemas.get(schemaUri) ?? "c:\\file.yaml";
121+
//ex: "file:///d:/Anton/GitHub/vscode-extension-dotnet-fastiot/schemas/template.fastiot.schema.yaml"
122+
const fileData = fs.readFileSync(file, 'utf8');
123+
return fileData;
124+
};
123125
//register
124-
this._yamlExtensionAPI.registerContributor(this._SCHEMA, this.onRequestSchemaURI, this.onRequestSchemaContent);
126+
this._yamlExtensionAPI.registerContributor(this._SCHEMA, onRequestSchemaURI, onRequestSchemaContent);
125127
//Diagnostics
126128
vscode.languages.onDidChangeDiagnostics(e => {
127129
e.uris.forEach(fileUri => {
128-
if(this._currentYamlFile==fileUri) {
130+
if(this._currentYamlFile.fsPath==fileUri.fsPath) {
129131
let diagnostics = vscode.languages.getDiagnostics(fileUri); // returns an array
130132
this._validationErrors=[];
131133
diagnostics.forEach(item => {
@@ -134,7 +136,7 @@ export class YamlRedHatServiceSingleton {
134136
//
135137
this._responseReceivedFlag=true;
136138
//close file
137-
this.closeFileIfOpen(fileUri);
139+
this.closeFileIfOpenAsync(fileUri);
138140
}
139141
});
140142
});
@@ -151,16 +153,15 @@ export class YamlRedHatServiceSingleton {
151153
private AddSchema(schemaFilePath:string) {
152154
//template.fastiot.schema.yaml
153155
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}`;
156+
//ex: "template.fastiot"
157+
const key = filename.substring(0,filename.length-31);
157158
//exist
158159
if(this._schemas.has(key)) return;
159160
//add
160161
this._schemas.set(key,schemaFilePath);
161162
}
162163

163-
public async ValidateSchema (yamlFilePath:string, schemaFilePath:string):Promise<IotResult> {
164+
public async ValidateSchemaAsync(yamlFilePath:string, schemaFilePath:string):Promise<IotResult> {
164165
let result:IotResult;
165166
try {
166167
//Add schema
@@ -169,17 +170,17 @@ export class YamlRedHatServiceSingleton {
169170
this._currentYamlFile=vscode.Uri.file(yamlFilePath);
170171
//adding a file to processing
171172
this._responseReceivedFlag=false;
172-
let ymldoc = await vscode.workspace.openTextDocument(vscode.Uri.file(yamlFilePath));
173+
await vscode.workspace.openTextDocument(vscode.Uri.file(yamlFilePath));
173174
//waiting response
174175
for (let i = 0; i < this._timeout; i++) {
175-
IoTHelper.Sleep(500);
176+
await IoTHelper.Sleep(500);
176177
if(this._responseReceivedFlag) i=this._timeout;
177178
}
178179
//response
179180
if(this._responseReceivedFlag) {
180181
//ok
181182
const msg=`Response received from Red Hat's YAML extension`;
182-
result = new IotResult(StatusResult.Error,msg);
183+
result = new IotResult(StatusResult.Ok,msg);
183184
if(this._validationErrors.length>0) {
184185
result.returnObject=this._validationErrors;
185186
}
@@ -196,14 +197,11 @@ export class YamlRedHatServiceSingleton {
196197
return Promise.resolve(result);
197198
}
198199

199-
private async closeFileIfOpen(file:vscode.Uri) : Promise<void> {
200+
private async closeFileIfOpenAsync(file:vscode.Uri) : Promise<void> {
200201
const tabs: vscode.Tab[] = vscode.window.tabGroups.all.map(tg => tg.tabs).flat();
201202
const index = tabs.findIndex(tab => tab.input instanceof vscode.TabInputText && tab.input.uri.path === file.path);
202203
if (index !== -1) {
203204
await vscode.window.tabGroups.close(tabs[index]);
204205
}
205206
}
206207
}
207-
208-
209-

src/Validator/YamlValidatorFork.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as path from 'path';
44
import { IotResult,StatusResult } from '../IotResult';
55
import { IYamlValidator } from './IYamlValidator';
66

7-
export class YamlValidatorFork implements IYamlValidator {
7+
export class YamlValidatorFork implements IYamlValidator {
88
private readonly _schemasFolderPath: string;
99

1010
constructor(schemasFolderPath: string){
Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
import * as vscode from 'vscode';
22
import * as fs from 'fs';
33
import * as path from 'path';
4+
import { IoTHelper } from '../Helper/IoTHelper';
45
import { IotResult,StatusResult } from '../IotResult';
56
import { IYamlValidator } from './IYamlValidator';
67
import { YamlRedHatServiceSingleton } from './YamlRedHatServiceSingleton';
8+
import { SSH2Stream } from 'ssh2-streams';
79

8-
export class YamlValidatorRedHat implements IYamlValidator {
10+
/*
11+
Sample:
12+
/init Extensin YamlRedHat
13+
let instanceExtension = YamlRedHatServiceSingleton.getInstance();
14+
let rez = await instanceExtension.ActivateAsync();
15+
console.log(rez.toString());
16+
const yamlFilePath="d:\\template.fastiot.yaml";
17+
const schemaFilePath="d:\\template.fastiot.schema.redhat.vscode-yaml.yaml";
18+
rez = await instanceExtension.ValidateSchemaAsync(yamlFilePath,schemaFilePath);
19+
console.log(rez.toString());
20+
*/
21+
22+
export class YamlValidatorRedHat {
923
private readonly _schemasFolderPath: string;
1024

1125
constructor(schemasFolderPath: string){
@@ -16,42 +30,33 @@ export class YamlValidatorRedHat implements IYamlValidator {
1630
{
1731
let result:IotResult;
1832
let validationErrors:Array<string>=[];
19-
let msg="";
2033
try {
34+
//init
2135
const instanceExtension = YamlRedHatServiceSingleton.getInstance();
22-
result=await instanceExtension.Activate();
23-
if(result.Status==StatusResult.Error)
24-
return Promise.resolve(result);
25-
26-
//source - https://www.npmjs.com/package/yaml-schema-validator-fork
27-
const validateSchema = require('yaml-schema-validator-fork');
28-
// validate a yml file
29-
const schemaPath=`${this._schemasFolderPath}\\${schemaFileName}`;
30-
var schemaErrors = validateSchema(yamlFilePath,
31-
{
32-
schemaPath: schemaPath,
33-
logLevel: 'verbose'
34-
}
35-
);
36-
//convert
37-
//schemaErrors = [{path: 'person.id', message: 'person.id must be a String'}]
38-
if(schemaErrors) {
39-
schemaErrors.forEach((element:any) => {
40-
const path=element.path;
41-
const message=element.message;
42-
msg=`path: ${path}, message: ${message}`;
43-
validationErrors.push(msg);
44-
});
45-
}
46-
result = new IotResult(StatusResult.Ok);
36+
result= await instanceExtension.ActivateAsync();
37+
if(result.Status==StatusResult.Error) {
38+
validationErrors.push(result.toString());
39+
result.returnObject=validationErrors;
40+
return Promise.resolve(result);
41+
}
42+
//process
43+
const schemaFilePath=path.join(this._schemasFolderPath, schemaFileName);
44+
result= await instanceExtension.ValidateSchemaAsync(yamlFilePath,schemaFilePath);
45+
if(result.Status==StatusResult.Error) {
46+
validationErrors.push(result.toString());
47+
result.returnObject=validationErrors;
48+
return Promise.resolve(result);
49+
}
50+
//result
51+
result.AddMessage(`${yamlFilePath} file has been validated`);
4752
} catch (err: any){
4853
//result
49-
result = new IotResult(StatusResult.Error,`VaidateSchema: pathFileYml = ${yamlFilePath}, schemaFileName = ${schemaFileName}`,err);
54+
const errorMsg=`Error ValidateSchema. pathFileYml = ${yamlFilePath}, schemaFileName = ${schemaFileName}`;
55+
result = new IotResult(StatusResult.Error,errorMsg,err);
5056
validationErrors.push(result.toString());
57+
result.returnObject=validationErrors;
5158
}
52-
result.returnObject=validationErrors;
53-
54-
return Promise.resolve(result);
59+
return result;
5560
}
56-
}
61+
}
5762

0 commit comments

Comments
 (0)