@@ -5,7 +5,11 @@ import * as vscode from 'vscode';
55import { executeCommandByExec } from "@/utils/cpUtils" ;
66import * as fs from "fs" ;
77import * as path from "path" ;
8+ import * as workspaceUtils from "@/utils/workspaceUtils" ;
9+ import * as TelemetryWrapper from "vscode-extension-telemetry-wrapper" ;
810
11+ const LATEST_VERSION = "latest" ;
12+ const versionPattern = / ^ v \d + ( \. \d + ) { 2 } \. j s o n $ / ;
913let topLevelTypes = [ "output" , "provider" , "resource" , "variable" , "data" ] ;
1014let topLevelRegexes = topLevelTypes . map ( o => {
1115 return {
@@ -53,7 +57,7 @@ export class TerraformTipsProvider implements CompletionItemProvider {
5357 token : CancellationToken ;
5458 resourceType : string | null = null ;
5559
56- public provideCompletionItems ( document : TextDocument , position : Position , token : CancellationToken , context : TerraformCompletionContext ) : CompletionItem [ ] {
60+ public async provideCompletionItems ( document : TextDocument , position : Position , token : CancellationToken , context : TerraformCompletionContext ) : Promise < CompletionItem [ ] > {
5761 this . document = document ;
5862 this . position = position ;
5963 this . token = token ;
@@ -62,7 +66,7 @@ export class TerraformTipsProvider implements CompletionItemProvider {
6266 const lineText = document . lineAt ( position . line ) . text ;
6367 const lineTillCurrentPosition = lineText . substring ( 0 , position . character ) ;
6468
65- // Are we trying to type a top type?
69+ // handle top level definition
6670 if ( this . isTopLevelType ( lineTillCurrentPosition ) ) {
6771 return this . getTopLevelType ( lineTillCurrentPosition ) ;
6872 }
@@ -102,7 +106,9 @@ export class TerraformTipsProvider implements CompletionItemProvider {
102106 // We're trying to type the exported field for the let
103107 const resourceType = parts [ 0 ] ;
104108 let resourceName = parts [ 1 ] ;
105- loadResource ( ) . then ( tips => {
109+ try {
110+ // async load resource config
111+ const tips = await loadResource ( ) ;
106112 const resources = tips . resource ;
107113 let attrs = resources [ resourceType ] . attrs ;
108114 let result = _ . map ( attrs , o => {
@@ -113,19 +119,19 @@ export class TerraformTipsProvider implements CompletionItemProvider {
113119 return c ;
114120 } ) ;
115121 return result ;
116- } ) . catch ( error => {
117- console . error ( "Can not load resource from json." ) ;
118- return ;
119- } ) ;
122+
123+ } catch ( error ) {
124+ console . error ( `Can not load resource from json. error:[ ${ error } ]` ) ;
125+ }
120126 }
121127
122128 // Which part are we completing for?
123129 return [ ] ;
124130 }
125131
126132 // Are we trying to type a parameter to a resource?
127- let possibleResources = this . checkTopLevelResource ( lineTillCurrentPosition ) ;
128- // typing a resource type
133+ let possibleResources = await this . checkTopLevelResource ( lineTillCurrentPosition ) ;
134+ // handle resource type
129135 if ( possibleResources . length > 0 ) {
130136 return this . getHintsForStrings ( possibleResources ) ;
131137 }
@@ -138,40 +144,43 @@ export class TerraformTipsProvider implements CompletionItemProvider {
138144 if ( endwithEqual ) {
139145 const lineBeforeEqualSign = lineTillCurrentPosition . substring ( 0 , includeEqual ) . trim ( ) ;
140146 // load options
141- loadResource ( ) . then ( tips => {
147+ try {
148+ // async load resource config
149+ const tips = await loadResource ( ) ;
142150 const name = lineBeforeEqualSign ;
143151 const resources = tips . resource ;
144152 const argStrs = this . findArgByName ( resources [ this . resourceType ] . args , name ) ;
145153 const options = this . getOptionsFormArg ( argStrs ) ;
146154 // clear resource type
147155 this . resourceType = "" ;
148156 return ( options ) . length ? options : [ ] ;
149- } ) . catch ( error => {
150- console . error ( "Can not load resource from json." ) ;
151- return [ ] ;
152- } ) ;
157+ } catch ( error ) {
158+ console . error ( `Can not load resource from json. error:[${ error } ]` ) ;
159+ }
153160 }
154161 this . resourceType = "" ;
155162 return [ ] ;
156163 }
157164
158- // Check if we're in a resource definition
165+ // handle argument
159166 if ( includeEqual < 0 && ! endwithEqual ) {
160167 // we're not in options case
161168 for ( let i = position . line - 1 ; i >= 0 ; i -- ) {
162169 let line = document . lineAt ( i ) . text ;
163170 let parentType = this . getParentType ( line ) ;
164171 if ( parentType && parentType . type === "resource" ) {
165- // typing a arg in resource
172+ // typing a argument in resource
166173 const resourceType = this . getResourceTypeFromLine ( line ) ;
167- loadResource ( ) . then ( tips => {
174+ try {
175+ // async load resource config
176+ const tips = await loadResource ( ) ;
168177 const resources = tips . resource ;
169178 const ret = this . getItemsForArgs ( resources [ resourceType ] . args , resourceType ) ;
170179 return ret ;
171- } ) . catch ( error => {
172- console . error ( " Can not load resource from json." ) ;
180+ } catch ( error ) {
181+ console . error ( ` Can not load resource from json. error:[ ${ error } ]` ) ;
173182 return [ ] ;
174- } ) ;
183+ }
175184 }
176185 else if ( parentType && parentType . type !== "resource" ) {
177186 // We don't want to accidentally include some other containers stuff
@@ -281,12 +290,15 @@ export class TerraformTipsProvider implements CompletionItemProvider {
281290 return "" ;
282291 }
283292
284- checkTopLevelResource ( lineTillCurrentPosition : string ) : any [ ] {
293+ async checkTopLevelResource ( lineTillCurrentPosition : string ) : Promise < any [ ] > {
285294 let parts = lineTillCurrentPosition . split ( " " ) ;
286295 if ( parts . length === 2 && parts [ 0 ] === "resource" ) {
287296 let r = parts [ 1 ] . replace ( / " / g, '' ) ;
288297 let regex = new RegExp ( "^" + r ) ;
289- loadResource ( ) . then ( tips => {
298+ // handle resource
299+ try {
300+ // async load resource config
301+ const tips = await loadResource ( ) ;
290302 const resources = tips . resource ;
291303 let possibleResources = _ . filter ( _ . keys ( resources ) , k => {
292304 if ( regex . test ( k ) ) {
@@ -295,11 +307,10 @@ export class TerraformTipsProvider implements CompletionItemProvider {
295307 return false ;
296308 } ) ;
297309 return possibleResources ;
298- } ) . catch ( error => {
299- console . error ( " Can not load resource from json." ) ;
310+ } catch ( error ) {
311+ console . error ( ` Can not load resource from json. error:[ ${ error } ]` ) ;
300312 return [ ] ;
301- } ) ;
302-
313+ }
303314 }
304315 return [ ] ;
305316 }
@@ -360,12 +371,14 @@ export class TerraformTipsProvider implements CompletionItemProvider {
360371
361372async function sortJsonFiles ( dir : string ) {
362373 const files = fs . readdirSync ( dir ) ;
363- const jsonFiles = files . filter ( file => path . extname ( file ) === '.json' ) ;
374+ const jsonFiles = files . filter ( file => path . extname ( file ) === '.json' && versionPattern . test ( file ) ) ;
375+ // const jsonFiles: string[] = ["v1.81.50.json", "v1.81.54.json"]; // debug
364376
365377 // import files
366378 const versions = await Promise . all ( jsonFiles . map ( async file => {
367- const jsonPath = path . join ( dir , file ) ;
368- const json = await import ( jsonPath ) ;
379+ const jsonPath = path . join ( "../config/tips/" , file ) ;
380+ // const json = await import(jsonPath);
381+ const json = require ( jsonPath ) ;
369382 const version = json . version as string ;
370383 return {
371384 json,
@@ -396,26 +409,35 @@ function compareVersions(a, b) {
396409 return 0 ;
397410}
398411
412+ // load resource config from json files based on the appropriate version
399413async function loadResource ( ) : Promise < Tips > {
400414 let tfVersion : string ;
401- await executeCommandByExec ( "terraform version" ) . then ( output => {
402- let match = output . match ( / t e n c e n t c l o u d s t a c k \/ t e n c e n t c l o u d \ ( v \d + \. \d + \. \d + ) / ) ;
415+ const cwd = workspaceUtils . getActiveEditorPath ( ) ;
416+ if ( ! cwd ) {
417+ TelemetryWrapper . sendError ( Error ( "noWorkspaceSelected" ) ) ;
418+ console . error ( `can not get path from active editor` ) ;
419+ }
420+
421+ await executeCommandByExec ( "terraform version" , cwd ) . then ( output => {
422+ let match = RegExp ( / t e n c e n t c l o u d s t a c k \/ t e n c e n t c l o u d ( v \d + \. \d + \. \d + ) / ) . exec ( output ) ;
403423
404424 if ( match ) {
405425 tfVersion = match [ 1 ] ;
406426 } else {
407- tfVersion = "latest" ;
427+ tfVersion = LATEST_VERSION ;
408428 }
409- console . log ( `version:v ${ tfVersion } ` ) ; //1.81.54
429+ console . log ( `tf provider version:[ ${ tfVersion } ],cwd:[ ${ cwd } ] ` ) ; //like: 1.81.54
410430 } ) . catch ( error => {
411431 console . error ( `execute terraform version failed: ${ error } ` ) ;
412432 } ) ;
413433
414- const tipFiles = await sortJsonFiles ( "../../config/tips" ) ;
434+ const tipsDir = path . join ( __dirname , '..' , 'config' , 'tips' ) ;
435+ const tipFiles = await sortJsonFiles ( tipsDir ) ;
415436 let result : Tips | null = null ;
416437
417438 tipFiles . some ( file => {
418439 if ( compareVersions ( tfVersion , file . version ) >= 0 ) {
440+ console . log ( `loaded json version:${ file . version } ` ) ;
419441 result = file . json as Tips ;
420442 return true ;
421443 }
0 commit comments