import { promises as fs } from 'fs' ; import { URL } from 'url' ; import { Connection } from 'vscode-languageserver' ; import { DidChangeWatchedFilesParams } from 'vscode-languageserver-protocol' ; import { parseAllDocuments } from 'yaml' ; import { IDocumentMetadata } from '../interfaces/documentMeta' ; import { fileExists , hasOwnProperty } from '../utils/misc' ; export class MetadataLibrary { private connection : Connection ; private metadata : Map < string , Thenable < IDocumentMetadata > > = new Map ( ) ; constructor ( connection ) { this . connection = connection ; } public get ( uri ) { const metadataUri = this . getAnsibleMetadataUri ( uri ) ; if ( metadataUri ) { let metadata = this . metadata . get ( metadataUri ) ; if ( ! metadata ) { metadata = this . readAnsibleMetadata ( metadataUri ) ; this . metadata . set ( metadataUri , metadata ) ; } return metadata ; } } public handleWatchedDocumentChange ( params ) { for ( const fileEvent of params . changes ) { this . metadata . delete ( fileEvent . uri ) ; } } returns private getAnsibleMetadataUri ( uri ) { let metaPath ; const pathArray = uri . split ( '/' ) ; for ( let index = pathArray . length - 1 ; index >= 0 ; index -- ) { if ( pathArray [ index ] === 'tasks' ) { metaPath = pathArray . slice ( 0 , index ) . concat ( 'meta' , 'main.yml' ) . join ( '/' ) ; } } return metaPath ; } private async readAnsibleMetadata ( metadataUri ) { const metadata = { source : metadataUri , collections : new Array < string > ( ) , } ; if ( await fileExists ( metadataUri ) ) { try { const metaContents = await fs . readFile ( new URL ( metadataUri ) , { encoding : 'utf8' , } ) ; parseAllDocuments ( metaContents ) . forEach ( ( metaDoc ) => { const metaObject = metaDoc . toJSON ( ) ; if ( hasOwnProperty ( metaObject , 'collections' ) && metaObject . collections instanceof Array ) { metaObject . collections . forEach ( ( collection ) => { if ( typeof collection === 'string' ) { metadata . collections . push ( collection ) ; } } ) ; } } ) ; } catch ( error ) { this . connection . window . showErrorMessage ( error ) ; } } return metadata ; } }