import path from 'path' ; import fs from 'fs' ; import { LanguageClient , window } from 'coc.nvim' ; import { installGoBin , runGoTool } from './utils/tools' ; import checkLatestTag from './utils/checktag' ; import { withProgress } from './utils/ui' ; import { getState , setState } from './utils/config' ; import { GOMODIFYTAGS , GOPLAY , GOPLS , GOTESTS , IMPL , TOOLS } from './binaries' ; import { compareVersions , isValidVersion } from './utils/versions' ; export async function version ( ) { const v1 = await pkgVersion ( ) ; const v2 = await goplsVersion ( ) || 'unknown' ; window . showMessage ( `Version: coc-go ${ v1 }; gopls ${ v2 }` , 'more' ) ; } export async function installGopls ( client ) { await installGoBin ( GOPLS , true , goplsVersion ) ; if ( client . needsStop ( ) ) { await client . stop ( ) ; client . restart ( ) ; } } const checkInterval = 24 * 60 * 60 * 1000 ; async function shouldCheckGopls ( ) { const now = new Date ( ) . getTime ( ) ; const last = await getState < number > ( 'gopls:last-check' ) ; if ( last - ( now - checkInterval ) < 0 ) { await setState ( 'gopls:last-check' , new Date ( ) . getTime ( ) ) ; return true ; } return false ; } export async function checkGopls ( client , mode ) { try { if ( ! ( await shouldCheckGopls ( ) ) ) { return ; } let install = false ; await withProgress ( 'Checking for new gopls version' , async ( ) => { const [ current , latest ] = await Promise . all ( [ goplsVersion ( ) , checkLatestTag ( "golang/tools" , /^gopls\// ) , ] ) ; if ( ! isValidVersion ( current ) || ! isValidVersion ( latest ) ) { window . showMessage ( 'checking for a new gopls version failed' , 'warning' ) ; return ; } switch ( compareVersions ( latest , current ) ) { case 0 : window . showMessage ( `[gopls] up-to-date: ${ current }` , 'more' ) ; break ; case 1 : switch ( mode ) { case 'install' : install = true ; break ; case 'ask' : install = await window . showPrompt ( `[gopls] Install update? ${ current } => ${ latest }` ) ; break ; case 'inform' : window . showMessage ( `[gopls] update available: ${ current } => ${ latest }` ) ; break ; } break ; case - 1 : window . showMessage ( `[gopls] current: ${ current } | latest: ${ latest }` , 'more' ) ; break ; } } ) ; if ( install ) { await installGopls ( client ) ; } } catch ( e ) { window . showMessage ( e . toString ( ) , 'error' ) ; } } async function pkgVersion ( ) { try { const pkgPath = path . resolve ( __dirname , '..' , 'package.json' ) ; const pkgContent = await fs . promises . readFile ( pkgPath , 'utf8' ) ; return JSON . parse ( pkgContent ) . version ; } catch ( err ) { console . error ( err ) ; } return '' ; } async function goplsVersion ( ) { const [ , versionOut ] = await runGoTool ( "gopls" , [ "version" ] ) ; const m = versionOut . trim ( ) . match ( /\s{4}golang\.org\/x\/tools\/gopls@(v?\d+\.\d+\.\d+) .*/ ) ; if ( m && isValidVersion ( m [ 1 ] ) ) { return m [ 1 ] . replace ( /^v/ , '' ) ; } return '' ; } export async function installGomodifytags ( ) { await installGoBin ( GOMODIFYTAGS , true ) ; } export async function installGotests ( ) { await installGoBin ( GOTESTS , true ) ; } export async function installGoplay ( ) { await installGoBin ( GOPLAY , true ) ; } export async function installImpl ( ) { await installGoBin ( IMPL , true ) ; } export async function installTools ( ) { for ( const tool of TOOLS ) { await installGoBin ( tool , true ) ; } }