@@ -13,6 +13,7 @@ import moment = require('moment');
1313import os = require( 'os' ) ;
1414import path = require( 'path' ) ;
1515import { promisify } from 'util' ;
16+ import semverCoerce from 'semver/functions/coerce' ;
1617import { getGoConfig , extensionInfo } from './config' ;
1718import { toolInstallationEnvironment } from './goEnv' ;
1819import { addGoStatus , goEnvStatusbarItem , outputChannel , removeGoStatus } from './goStatus' ;
@@ -549,7 +550,12 @@ export async function getLatestGoVersions(): Promise<GoEnvironmentOption[]> {
549550}
550551
551552const STATUS_BAR_ITEM_NAME = 'Go Update Notification' ;
552- const dismissedGoVersionUpdatesKey = 'dismissedGoVersionUpdates' ;
553+
554+ /**
555+ * Key for the global state that tracks Go versions for which the user has
556+ * explicitly dismissed the upgrade notification.
557+ */
558+ const DISMISSED_GO_VERSION_KEY = 'dismissedGoVersionUpdates' ;
553559
554560export async function offerToInstallLatestGoVersion ( ctx : Pick < vscode . ExtensionContext , 'subscriptions' > ) {
555561 if ( extensionInfo . isInCloudIDE ) {
@@ -564,83 +570,96 @@ export async function offerToInstallLatestGoVersion(ctx: Pick<vscode.ExtensionCo
564570 return ;
565571 }
566572
567- let options = await getLatestGoVersions ( ) ;
573+ let latestVersions = await getLatestGoVersions ( ) ;
574+
575+ const currentVersion = await getGoVersion ( ) ;
576+
577+ // The official support for vscode-go is last three minor versions of Go.
578+ // Try to start with last four minor versions.
579+ let minimumVersion = semverCoerce ( latestVersions [ 0 ] . label ) ;
580+ if ( minimumVersion ) {
581+ minimumVersion . minor = minimumVersion . minor - 3 ;
582+ minimumVersion . patch = 0 ;
583+ }
584+
585+ const download = {
586+ title : 'Download' ,
587+ async command ( ) {
588+ await vscode . env . openExternal ( vscode . Uri . parse ( 'https://go.dev/dl/' ) ) ;
589+ }
590+ } ;
591+
592+ // Popup if the Go version is beyond support.
593+ if ( minimumVersion && currentVersion . lt ( minimumVersion . format ( ) ) ) {
594+ let text = `The minimum supported Go version is ${ minimumVersion . format ( ) } . Please update your Go to ensure the extension functions correctly. You are currently using ${ formatGoVersion (
595+ currentVersion
596+ ) } .`;
597+ vscode . window . showInformationMessage ( text , download ) . then ( ( selection ) => {
598+ selection ?. command ( ) ;
599+ } ) ;
600+ }
568601
569602 // Filter out Go versions the user has already dismissed.
570- let dismissedOptions : GoEnvironmentOption [ ] ;
571- dismissedOptions = await getFromGlobalState ( dismissedGoVersionUpdatesKey ) ;
572- if ( dismissedOptions ) {
573- options = options . filter ( ( version ) => ! dismissedOptions . find ( ( x ) => x . label === version . label ) ) ;
603+ const dismissedVersions : GoEnvironmentOption [ ] = await getFromGlobalState ( DISMISSED_GO_VERSION_KEY ) ;
604+ if ( dismissedVersions ) {
605+ latestVersions = latestVersions . filter ( ( version ) => ! dismissedVersions . find ( ( x ) => x . label === version . label ) ) ;
574606 }
575607
576- // Compare to current go version.
577- const currentVersion = await getGoVersion ( ) ;
608+ // Filter out Go versions below the current go versions.
578609 if ( currentVersion ) {
579- options = options . filter ( ( version ) => currentVersion . lt ( version . label ) ) ;
610+ latestVersions = latestVersions . filter ( ( version ) => currentVersion . lt ( version . label ) ) ;
580611 }
581612
582613 // Notify user that there is a newer version of Go available.
583- if ( options . length > 0 ) {
584- const versionsText = options . map ( ( x ) => x . label ) . join ( ', ' ) ;
585- const statusBarItem = addGoStatus ( STATUS_BAR_ITEM_NAME ) ;
586- statusBarItem . name = STATUS_BAR_ITEM_NAME ;
587- statusBarItem . text = 'New Go version is available' ;
588- statusBarItem . detail = versionsText ;
589- statusBarItem . command = {
590- title : 'Upgrade' ,
591- command : 'go.promptforgoinstall' ,
592- arguments : [ options ] ,
593- tooltip : 'Upgrade or silence notification'
594- } ;
595- // TODO: Error level is more visible. Consider to make it configurable?
596- statusBarItem . severity = vscode . LanguageStatusSeverity . Warning ;
597-
614+ if ( latestVersions . length > 0 ) {
598615 ctx . subscriptions . push (
599616 vscode . commands . registerCommand ( 'go.promptforgoinstall' , ( ) => {
600- const download = {
601- title : 'Download' ,
602- async command ( ) {
603- await vscode . env . openExternal ( vscode . Uri . parse ( 'https://go.dev/dl/' ) ) ;
604- }
605- } ;
606-
607617 const neverAgain = {
608618 title : "Don't Show Again" ,
609619 async command ( ) {
610620 // Mark these versions as seen.
611- dismissedOptions = await getFromGlobalState ( dismissedGoVersionUpdatesKey ) ;
612- if ( ! dismissedOptions ) {
613- dismissedOptions = [ ] ;
621+ let dismissedVersions : GoEnvironmentOption [ ] = await getFromGlobalState (
622+ DISMISSED_GO_VERSION_KEY
623+ ) ;
624+ if ( ! dismissedVersions ) {
625+ dismissedVersions = [ ] ;
614626 }
615- options . forEach ( ( version ) => {
616- dismissedOptions . push ( version ) ;
627+ latestVersions . forEach ( ( version ) => {
628+ dismissedVersions . push ( version ) ;
617629 } ) ;
618- await updateGlobalState ( dismissedGoVersionUpdatesKey , dismissedOptions ) ;
630+ await updateGlobalState ( DISMISSED_GO_VERSION_KEY , dismissedVersions ) ;
619631 }
620632 } ;
621633
622- let versionsText : string ;
623- if ( options . length > 1 ) {
624- versionsText = `${ options
634+ let text : string ;
635+ if ( latestVersions . length > 1 ) {
636+ text = `${ latestVersions
625637 . map ( ( x ) => x . label )
626638 . reduce ( ( prev , next ) => {
627639 return prev + ' and ' + next ;
628640 } ) } are available`;
629641 } else {
630- versionsText = `${ options [ 0 ] . label } is available` ;
642+ text = `${ latestVersions [ 0 ] . label } is available. ` ;
631643 }
632-
633- vscode . window
634- . showInformationMessage (
635- `${ versionsText } . You are currently using ${ formatGoVersion ( currentVersion ) } .` ,
636- download ,
637- neverAgain
638- )
639- . then ( ( selection ) => {
640- selection ?. command ( ) ;
641- removeGoStatus ( STATUS_BAR_ITEM_NAME ) ;
642- } ) ;
644+ text = text + ` You are currently using ${ formatGoVersion ( currentVersion ) } .` ;
645+ vscode . window . showInformationMessage ( text , download , neverAgain ) . then ( ( selection ) => {
646+ selection ?. command ( ) ;
647+ removeGoStatus ( STATUS_BAR_ITEM_NAME ) ;
648+ } ) ;
643649 } )
644650 ) ;
651+
652+ const statusBarItem = addGoStatus ( STATUS_BAR_ITEM_NAME ) ;
653+ statusBarItem . name = STATUS_BAR_ITEM_NAME ;
654+ statusBarItem . text = 'New Go version is available' ;
655+ statusBarItem . detail = latestVersions . map ( ( x ) => x . label ) . join ( ', ' ) ;
656+ statusBarItem . command = {
657+ title : 'Upgrade' ,
658+ command : 'go.promptforgoinstall' ,
659+ arguments : [ latestVersions ] ,
660+ tooltip : 'Upgrade or silence notification'
661+ } ;
662+ // TODO: Error level is more visible. Consider to make it configurable?
663+ statusBarItem . severity = vscode . LanguageStatusSeverity . Warning ;
645664 }
646665}
0 commit comments