Skip to content

Commit

Permalink
Warn user of old version in "func help" (#3327)
Browse files Browse the repository at this point in the history
* Checking the latest version against the current version.

* Check the latest version in the help command.

* Addressed the review comments.
  • Loading branch information
khkh-ms authored Aug 28, 2023
1 parent b1f7ab2 commit 090525f
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/Azure.Functions.Cli/Actions/HelpAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public HelpAction(IEnumerable<TypeAttributePair> actions, Func<Type, IAction> cr

public async override Task RunAsync()
{
var latestVersionMessageTask = VersionHelper.CheckLatestVersionAsync();
ScriptHostHelpers.SetIsHelpRunning();
if (!string.IsNullOrEmpty(_context) || !string.IsNullOrEmpty(_subContext))
{
Expand Down Expand Up @@ -95,9 +96,27 @@ public async override Task RunAsync()
{
DisplayGeneralHelp();
}

await ShowLatestVersionMessage(latestVersionMessageTask);
return;
}

private static async Task ShowLatestVersionMessage(Task<string> latestVersionMessageTask)
{
try
{
var latestVersionMessage = await latestVersionMessageTask;
if (!string.IsNullOrEmpty(latestVersionMessage))
{
ColoredConsole.WriteLine(WarningColor($"{latestVersionMessage}{Environment.NewLine}"));
}
}
catch (Exception)
{
// ignore
}
}

private async Task<bool> ShowCreateActionHelp()
{
var actionType = _actionTypes.First(x => x.Names.Contains("new"));
Expand Down
2 changes: 2 additions & 0 deletions src/Azure.Functions.Cli/Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ internal static class Constants
public const int DefaultGetFunctionReadinessTime = 30000;
public const int DefaultRestartedWorkerProcessUptimeWithin = 45000;
public const string HelpCommand = "help";
public const string CoreToolsVersionsFeedUrl = "https://functionscdn.azureedge.net/public/cli-feed-v4.json";
public const string OldCoreToolsVersionMessage = "You are using an old Core Tools version. Please upgrade to the latest version.";
public const string GetFunctionNameParamId = "trigger-functionName";
public const string GetFileNameParamId = "app-selectedFileName";
public const string UserPromptBooleanType = "boolean";
Expand Down
145 changes: 145 additions & 0 deletions src/Azure.Functions.Cli/Helpers/VersionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
using Azure.Functions.Cli.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;

namespace Azure.Functions.Cli.Helpers
{
internal class VersionHelper
{

// Check that current core tools is the latest version.
// To ensure that it doesn't block other tasks. The HTTP Request timeout is only 1 second.
// We simply ingnore the exception if for any reason the check fails.
public static async Task<string> CheckLatestVersionAsync()
{
try
{
var client = new System.Net.Http.HttpClient
{
Timeout = TimeSpan.FromSeconds(1)
};
var response = await client.GetAsync(Constants.CoreToolsVersionsFeedUrl);
var content = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<CliFeed>(content);
IEnumerable releases = ((IEnumerable) data.Releases);
var releaseList = new List<ReleaseSummary>();
foreach (var item in releases)
{
var jProperty = (Newtonsoft.Json.Linq.JProperty)item;
var releaseDetail = JsonConvert.DeserializeObject<ReleaseDetail>(jProperty.Value.ToString());
releaseList.Add(new ReleaseSummary() { Release = jProperty.Name, ReleaseDetail = releaseDetail.ReleaseList.FirstOrDefault() });
}

var latestCoreToolsReleaseVersion = releaseList.FirstOrDefault(x => x.Release == data.Tags.V4Release.ReleaseVersion)?.CoreToolsReleaseNumber;

if (!string.IsNullOrEmpty(latestCoreToolsReleaseVersion) &&
Constants.CliVersion != latestCoreToolsReleaseVersion)
{
return Constants.OldCoreToolsVersionMessage;
}

return string.Empty;
}
catch (Exception)
{
return string.Empty;
}
}

private class CliFeed
{
[JsonProperty("tags")]
public Tags Tags { get; set; }

[JsonProperty("releases")]
public Object Releases { get; set; }
}

private class Tags
{
[JsonProperty("v4")]
public Release V4Release { get; set; }

[JsonProperty("v4-prerelease")]
public Release V4PreRelease { get; set; }

[JsonProperty("v3")]
public Release V3Release { get; set; }

[JsonProperty("v3-prerelease")]
public Release V3PreRelease { get; set; }
}

private class Release
{
[JsonProperty("release")]
public string ReleaseVersion { get; set; }

[JsonProperty("releaseQuality")]
public string ReleaseQuality { get; set; }

[JsonProperty("hidden")]
public bool Hidden { get; set; }
}

private class ReleaseSummary
{
public string Release { get; set; }

public string CoreToolsReleaseNumber
{
get
{
var downloadLink = ReleaseDetail?.DownloadLink;
if (string.IsNullOrEmpty(ReleaseDetail?.DownloadLink))
{
return string.Empty;
}

Uri uri = new UriBuilder(ReleaseDetail?.DownloadLink).Uri;

if (uri.Segments.Length < 4)
{
return string.Empty;
}

return uri.Segments[2].Replace("/", string.Empty);
}
}
public CoreToolsRelease ReleaseDetail { get; set; }
}

private class ReleaseDetail
{
[JsonProperty("coreTools")]
public IList<CoreToolsRelease> ReleaseList { get; set; }
}

private class CoreToolsRelease
{
[JsonProperty("OS")]
public string Os { get; set; }

[JsonProperty("Architecture")]
public string Architecture { get; set; }

[JsonProperty("downloadLink")]
public string DownloadLink { get; set; }

[JsonProperty("size")]
public string Size { get; set; }

[JsonProperty("default")]
public bool Default { get; set; }
}
}


}

0 comments on commit 090525f

Please sign in to comment.