Skip to content

Commit 6cf8c87

Browse files
committed
enable json load
1 parent 04c8dbc commit 6cf8c87

File tree

7 files changed

+39931
-37392
lines changed

7 files changed

+39931
-37392
lines changed

config/tips/tiat-resources_bak.json

-37,366
This file was deleted.

config/tips/v1.81.54.json

+39,771
Large diffs are not rendered by default.

src/autocomplete/TerraformHoverProvider.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { HoverProvider, TextDocument, Position, CancellationToken, CompletionItem, CompletionItemKind, Hover, ProviderResult } from "vscode";
2-
import resources from '../../config/tips/tiat-resources.json';
32
import * as _ from "lodash";
43

54
var topLevelTypes = ["output", "provider", "resource", "variable", "data"];

src/autocomplete/TerraformTipsProvider.ts

+141-24
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { CompletionItemProvider, TextDocument, Position, CancellationToken, CompletionItem, CompletionItemKind } from "vscode";
2-
import resources from '../../config/tips/tiat-resources.json';
2+
// import resources from '../../config/tips/tiat-resources.json';
33
import * as _ from "lodash";
44
import * as vscode from 'vscode';
5+
import { executeCommandByExec } from "@/utils/cpUtils";
6+
import * as fs from "fs";
7+
import * as path from "path";
58

69
let topLevelTypes = ["output", "provider", "resource", "variable", "data"];
710
let topLevelRegexes = topLevelTypes.map(o => {
@@ -15,6 +18,29 @@ interface TerraformCompletionContext extends vscode.CompletionContext {
1518
resourceType?: string;
1619
}
1720

21+
interface Argument {
22+
name: string;
23+
description: string;
24+
options?: Array<string>;
25+
detail?: Array<Argument>;
26+
}
27+
28+
interface Attribute {
29+
name: string;
30+
description: string;
31+
detail?: Array<Attribute>;
32+
}
33+
34+
interface Tips {
35+
version: string;
36+
resource: {
37+
[key: string]: {
38+
args: Array<Argument>;
39+
attrs: Array<Attribute>;
40+
};
41+
};
42+
}
43+
1844
const TEXT_MIN_SORT = "a";
1945
const TEXT_FILTER = " ";
2046

@@ -76,15 +102,21 @@ export class TerraformTipsProvider implements CompletionItemProvider {
76102
// We're trying to type the exported field for the let
77103
const resourceType = parts[0];
78104
let resourceName = parts[1];
79-
let attrs = resources[resourceType].attrs;
80-
let result = _.map(attrs, o => {
81-
let c = new CompletionItem(`${o.name} (${resourceType})`, CompletionItemKind.Property);
82-
c.detail = o.description;
83-
c.insertText = o.name;
84-
c.sortText = TEXT_MIN_SORT;
85-
return c;
105+
loadResource().then(tips => {
106+
const resources = tips.resource;
107+
let attrs = resources[resourceType].attrs;
108+
let result = _.map(attrs, o => {
109+
let c = new CompletionItem(`${o.name}(${resourceType})`, CompletionItemKind.Property);
110+
c.detail = o.description;
111+
c.insertText = o.name;
112+
c.sortText = TEXT_MIN_SORT;
113+
return c;
114+
});
115+
return result;
116+
}).catch(error => {
117+
console.error("Can not load resource from json.");
118+
return;
86119
});
87-
return result;
88120
}
89121

90122
// Which part are we completing for?
@@ -106,12 +138,18 @@ export class TerraformTipsProvider implements CompletionItemProvider {
106138
if (endwithEqual) {
107139
const lineBeforeEqualSign = lineTillCurrentPosition.substring(0, includeEqual).trim();
108140
// load options
109-
const name = lineBeforeEqualSign;
110-
const argStrs = this.findArgByName(resources[this.resourceType].args, name);
111-
const options = this.getOptionsFormArg(argStrs);
112-
// clear resource type
113-
this.resourceType = "";
114-
return (options).length ? options : [];
141+
loadResource().then(tips => {
142+
const name = lineBeforeEqualSign;
143+
const resources = tips.resource;
144+
const argStrs = this.findArgByName(resources[this.resourceType].args, name);
145+
const options = this.getOptionsFormArg(argStrs);
146+
// clear resource type
147+
this.resourceType = "";
148+
return (options).length ? options : [];
149+
}).catch(error => {
150+
console.error("Can not load resource from json.");
151+
return [];
152+
});
115153
}
116154
this.resourceType = "";
117155
return [];
@@ -126,8 +164,14 @@ export class TerraformTipsProvider implements CompletionItemProvider {
126164
if (parentType && parentType.type === "resource") {
127165
// typing a arg in resource
128166
const resourceType = this.getResourceTypeFromLine(line);
129-
const ret = this.getItemsForArgs(resources[resourceType].args, resourceType);
130-
return ret;
167+
loadResource().then(tips => {
168+
const resources = tips.resource;
169+
const ret = this.getItemsForArgs(resources[resourceType].args, resourceType);
170+
return ret;
171+
}).catch(error => {
172+
console.error("Can not load resource from json.");
173+
return [];
174+
});
131175
}
132176
else if (parentType && parentType.type !== "resource") {
133177
// We don't want to accidentally include some other containers stuff
@@ -242,13 +286,20 @@ export class TerraformTipsProvider implements CompletionItemProvider {
242286
if (parts.length === 2 && parts[0] === "resource") {
243287
let r = parts[1].replace(/"/g, '');
244288
let regex = new RegExp("^" + r);
245-
let possibleResources = _.filter(_.keys(resources), k => {
246-
if (regex.test(k)) {
247-
return true;
248-
}
249-
return false;
289+
loadResource().then(tips => {
290+
const resources = tips.resource;
291+
let possibleResources = _.filter(_.keys(resources), k => {
292+
if (regex.test(k)) {
293+
return true;
294+
}
295+
return false;
296+
});
297+
return possibleResources;
298+
}).catch(error => {
299+
console.error("Can not load resource from json.");
300+
return [];
250301
});
251-
return possibleResources;
302+
252303
}
253304
return [];
254305
}
@@ -305,4 +356,70 @@ export class TerraformTipsProvider implements CompletionItemProvider {
305356
}
306357
}
307358
}
308-
}
359+
}
360+
361+
async function sortJsonFiles(dir: string) {
362+
const files = fs.readdirSync(dir);
363+
const jsonFiles = files.filter(file => path.extname(file) === '.json');
364+
365+
// import files
366+
const versions = await Promise.all(jsonFiles.map(async file => {
367+
const jsonPath = path.join(dir, file);
368+
const json = await import(jsonPath);
369+
const version = json.version as string;
370+
return {
371+
json,
372+
version
373+
};
374+
}));
375+
376+
// sort with version desc
377+
versions.sort((a, b) => compareVersions(b.version, a.version));
378+
379+
return versions;
380+
}
381+
382+
function compareVersions(a, b) {
383+
if (a === 'latest') { return 1; }
384+
if (b === 'latest') { return -1; }
385+
const aParts = a.split('.').map(Number);
386+
const bParts = b.split('.').map(Number);
387+
388+
for (let i = 0; i < aParts.length; i++) {
389+
if (aParts[i] > bParts[i]) {
390+
return 1;
391+
} else if (aParts[i] < bParts[i]) {
392+
return -1;
393+
}
394+
}
395+
//equal
396+
return 0;
397+
}
398+
399+
async function loadResource(): Promise<Tips> {
400+
let tfVersion: string;
401+
await executeCommandByExec("terraform version").then(output => {
402+
let match = output.match(/tencentcloudstack\/tencentcloud\ (v\d+\.\d+\.\d+)/);
403+
404+
if (match) {
405+
tfVersion = match[1];
406+
} else {
407+
tfVersion = "latest";
408+
}
409+
console.log(`version:v${tfVersion}`); //1.81.54
410+
}).catch(error => {
411+
console.error(`execute terraform version failed: ${error}`);
412+
});
413+
414+
const tipFiles = await sortJsonFiles("../../config/tips");
415+
let result: Tips | null = null;
416+
417+
tipFiles.some(file => {
418+
if (compareVersions(tfVersion, file.version) >= 0) {
419+
result = file.json as Tips;
420+
return true;
421+
}
422+
return false;
423+
});
424+
return result;
425+
}

src/client/runner/terraformRunner.ts

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class TerraformRunner extends BaseRunner {
3434

3535
this.setAKSK();
3636

37+
terraformShellManager.getShell().runTerraformCmd(TerraformCommand.Version);
3738
terraformShellManager.getShell().runTerraformCmd(TerraformCommand.Init);
3839

3940
return "init success";
@@ -60,6 +61,10 @@ export class TerraformRunner extends BaseRunner {
6061
);
6162
}
6263

64+
public async executeVersion(params: type): Promise<string> {
65+
66+
}
67+
6368
public async preImport(cwd: string, args: any, file: string): Promise<{ importArgs: string, tfFile: string }> {
6469
const fileName = (file === undefined) ? args.resource.type + '.tf' : file;
6570

src/commons/customCmdRegister.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export enum TerraformCommand {
1616
Destroy = "terraform destroy",
1717
Validate = "terraform validate",
1818
Show = "terraform show",
19-
State = "terraform state"
19+
State = "terraform state",
20+
Version = "terraform version"
2021
}
2122

2223
export enum TerraformerCommand {

src/utils/cpUtils.ts

+12
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,15 @@ export async function executeCommand(command: string, args: string[], options: c
4242
});
4343
});
4444
}
45+
46+
export async function executeCommandByExec(command: string): Promise<string> {
47+
return new Promise((resolve, reject) => {
48+
cp.exec(command, (error, stdout, stderr) => {
49+
if (error) {
50+
reject(`child_process exec failed: error:[${error}], stderr:[${stderr}]`);
51+
} else {
52+
resolve(stdout);
53+
}
54+
});
55+
});
56+
}

0 commit comments

Comments
 (0)