Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: CLI release channels #300

Merged
merged 18 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions Snyk.Common/Settings/ISnykOptions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Snyk.Common.Authentication;
using Snyk.Common.Service;

namespace Snyk.Common.Settings
{
Expand Down Expand Up @@ -73,7 +73,9 @@ public interface ISnykOptions
/// Gets or sets the value of the CLI custom path. If empty, the default path from AppData would be used.
/// </summary>
string CliCustomPath { get; set; }

string CliReleaseChannel { get; set; }
string CliDownloadUrl { get; set; }
ISet<string> TrustedFolders { get; set; }
/// <summary>
/// Settings changed event.
/// </summary>
Expand All @@ -100,11 +102,6 @@ public interface ISnykOptions
/// <returns>Returns true if authenticated successfully, or if a valid token was loaded from storage.</returns>
bool Authenticate();

/// <summary>
/// Force Visual Studio to load Settings from storage.
/// </summary>
void LoadSettingsFromStorage();

SastSettings SastSettings { get; set; }
Task OnAuthenticationSuccessfulAsync(string token);
Task OnAuthenticationFailedAsync(string errorMessage);
Expand Down
7 changes: 0 additions & 7 deletions Snyk.VisualStudio.Extension.2022/CLI/ICliProvider.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ protected bool IsButtonAvailable()
{
ThreadHelper.ThrowIfNotOnUIThread();
var isLsReady = SnykVSPackage.Instance?.LanguageClientManager?.IsReady ?? false;
return SnykVSPackage.ServiceProvider.Options.ApiToken.IsValid()
&& SnykSolutionService.Instance.IsSolutionOpen() && isLsReady;
return SnykSolutionService.Instance.IsSolutionOpen() && isLsReady;
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ public static async Task InitializeAsync(AsyncPackage package)
public override async Task UpdateStateAsync()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var isLsReady = SnykVSPackage.Instance?.LanguageClientManager?.IsReady ?? false;

this.MenuCommand.Enabled = SnykVSPackage.ServiceProvider.Options.ApiToken.IsValid()
&& this.VsPackage.ToolWindowControl.IsTreeContentNotEmpty() && isLsReady;
this.MenuCommand.Enabled = this.VsPackage.ToolWindowControl.IsTreeContentNotEmpty();
}

/// <summary>
Expand Down
75 changes: 37 additions & 38 deletions Snyk.VisualStudio.Extension.2022/Download/SnykCliDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Serilog;
using Snyk.Common;
using Snyk.Common.Settings;
using Snyk.VisualStudio.Extension.CLI;
using Snyk.VisualStudio.Extension.Language;
using Snyk.VisualStudio.Extension.Service;
Expand All @@ -16,26 +17,26 @@ namespace Snyk.VisualStudio.Extension.Download
/// </summary>
public class SnykCliDownloader
{
private const string BaseUrl = "https://downloads.snyk.io";
public const string DefaultBaseDownloadUrl = "https://downloads.snyk.io";
public const string DefaultReleaseChannel = "preview";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will switch to default stable before GA


private const string ReleaseChannel = "preview";
private const string LatestReleaseVersionUrl = BaseUrl + "/cli/" + ReleaseChannel + "/ls-protocol-version-" + LsConstants.ProtocolVersion;
private const string LatestReleaseDownloadUrl = BaseUrl + "/cli/{0}/" + SnykCli.CliFileName;
private const string LatestReleaseVersionUrlScheme = "{0}/cli/{1}/ls-protocol-version-" + LsConstants.ProtocolVersion;
private const string LatestReleaseDownloadUrlScheme = "{0}/cli/{1}/" + SnykCli.CliFileName;
private const string Sha256DownloadUrl = "{0}.sha256";

private const int FourDays = 4;

private static readonly ILogger Logger = LogManager.ForContext<SnykCliDownloader>();

private readonly ISnykOptions SnykOptions;
private readonly string currentCliVersion;

private string expectedSha;

/// <summary>
/// Initializes a new instance of the <see cref="SnykCliDownloader"/> class.
/// </summary>
/// <param name="currentCliVersion">Initial CLI version parameter.</param>
public SnykCliDownloader(string currentCliVersion) => this.currentCliVersion = currentCliVersion;
public SnykCliDownloader(ISnykOptions snykOptions, string currentVersion)
{
this.SnykOptions = snykOptions;
this.currentCliVersion = currentVersion;
}

/// <summary>
/// Callback on download finished event.
Expand All @@ -52,6 +53,13 @@ public static string GetCliFilePath(string customCliPath) => string.IsNullOrEmpt
? SnykCli.GetSnykCliDefaultPath()
: customCliPath;


public static bool IsCliFileFound(string cliCustomPath)
{
var path = GetCliFilePath(cliCustomPath);
return File.Exists(path);
}

/// <summary>
/// Request last cli information.
/// </summary>
Expand All @@ -64,12 +72,15 @@ public LatestReleaseInfo GetLatestReleaseInfo()
{
Logger.Information("Get latest CLI release info");

string latestVersion = webClient.DownloadString(LatestReleaseVersionUrl).Replace("\n", string.Empty);
var latestReleaseVersionUrl = string.Format(LatestReleaseVersionUrlScheme, SnykOptions.CliDownloadUrl, SnykOptions.CliReleaseChannel);
var latestVersion = webClient.DownloadString(latestReleaseVersionUrl).Replace("\n", string.Empty);

var latestReleaseDownloadUrl = string.Format(LatestReleaseDownloadUrlScheme, SnykOptions.CliDownloadUrl, "v"+latestVersion);

return new LatestReleaseInfo
{
Version = latestVersion,
Url = string.Format(LatestReleaseDownloadUrl, "v"+latestVersion),
Version = "v" + latestVersion,
Url = latestReleaseDownloadUrl,
Name = "v" + latestVersion,
};
}
Expand Down Expand Up @@ -108,29 +119,27 @@ public string GetLatestCliSha(string cliDownloadUrl)
}
}

/// <summary>
/// Check is four days passed after lact check.
/// </summary>
/// <param name="lastCheckDate">Last check date value.</param>
/// <returns>True if four days passed after last check.</returns>
public bool IsFourDaysPassedAfterLastCheck(DateTime lastCheckDate)
=> (DateTime.Now - lastCheckDate).TotalDays > FourDays;

/// <summary>
/// Check is CLI download needed.
/// 1. If CLI file not exists.
/// 2. If new CLI release exists.
/// </summary>
/// <param name="lastCheckDate">Last check date.</param>
/// <param name="cliFileDestinationPath">Path to CLI file.</param>
/// <returns>True if CLI file not exists or new release exists.</returns>
public bool IsCliDownloadNeeded(DateTime lastCheckDate, string cliFileDestinationPath = null)
public bool IsCliDownloadNeeded(string cliFileDestinationPath = null)
{
if (!this.IsCliFileExists(cliFileDestinationPath) || this.IsCliUpdateExists(lastCheckDate))
try
{
return true;
if (!this.IsCliFileExists(cliFileDestinationPath) || this.IsNewVersionAvailable(this.currentCliVersion, this.GetLatestReleaseInfo().Version))
{
return true;
}
}
catch (Exception ex)
{
Logger.Error("Could not fetch latest CLI release info for provided version {Ex}", ex);
return false;
}

return false;
}

Expand All @@ -141,30 +150,20 @@ public bool IsCliDownloadNeeded(DateTime lastCheckDate, string cliFileDestinatio
/// <returns>True if CLI file not exists.</returns>
public bool IsCliFileExists(string cliFileDestinationPath = null) => File.Exists(cliFileDestinationPath);

/// <summary>
/// Is CLI update exists.
/// </summary>
/// <param name="lastCheckDate">Last check date.</param>
/// <returns>True if new version CLI exists</returns>
public bool IsCliUpdateExists(DateTime lastCheckDate) => this.IsNewVersionAvailable(this.currentCliVersion, this.GetLatestReleaseInfo().Version) && this.IsFourDaysPassedAfterLastCheck(lastCheckDate);

/// <summary>
/// Check is there a new version on the server and if there is, download it.
/// </summary>
/// <param name="progressWorker">Progress worker for update get download progress.</param>
/// <param name="lastCheckDate">Last date when it check for CLI updates.</param>
/// <param name="filePath">CLI file destination path or null.</param>
/// <param name="downloadFinishedCallbacks">List of callback for download finished event.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task AutoUpdateCliAsync(
ISnykProgressWorker progressWorker,
DateTime lastCheckDate,
public async Task AutoUpdateCliAsync(ISnykProgressWorker progressWorker,
string filePath = null,
List<CliDownloadFinishedCallback> downloadFinishedCallbacks = null)
{
var fileDestinationPath = GetCliFilePath(filePath);

var isCliDownloadNeeded = this.IsCliDownloadNeeded(lastCheckDate, fileDestinationPath);
var isCliDownloadNeeded = this.IsCliDownloadNeeded(fileDestinationPath);

if (isCliDownloadNeeded)
{
Expand Down
16 changes: 14 additions & 2 deletions Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.LanguageServer.Client;
Expand Down Expand Up @@ -65,6 +66,7 @@ public object GetInitializationOptions()
SendErrorReports = "true",
ManageBinariesAutomatically = options.BinariesAutoUpdate.ToString(),
EnableTrustedFoldersFeature = "false",
TrustedFolders = options.TrustedFolders.ToList(),
IntegrationName = options.IntegrationName,
FilterSeverity = new FilterSeverityOptions
{
Expand Down Expand Up @@ -188,8 +190,18 @@ public async Task StopServerAsync()
{
if (StopAsync != null)
{
await StopAsync.InvokeAsync(this, EventArgs.Empty);
IsReady = false;
try
{
await StopAsync.InvokeAsync(this, EventArgs.Empty);
}
catch (Exception ex)
{
Logger.Error("Could not stop Language Server. {Ex}", ex);
}
finally
{
IsReady = false;
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@ public interface ISnykServiceProvider
/// </summary>
SnykToolWindowControl ToolWindow { get; }

/// <summary>
/// Create new instance of <see cref="SnykCli"/>.
/// </summary>
/// <returns>SnykCli.</returns>
ICli NewCli();

/// <summary>
/// Get Visual Studio service (async).
/// </summary>
Expand Down
16 changes: 1 addition & 15 deletions Snyk.VisualStudio.Extension.2022/Service/SnykService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Snyk.VisualStudio.Extension.Service
/// <summary>
/// Main logic for Snyk extension.
/// </summary>
public class SnykService : ISnykServiceProvider, ISnykService, ICliProvider
public class SnykService : ISnykServiceProvider, ISnykService
{
private static readonly ILogger Logger = LogManager.ForContext<SnykService>();

Expand Down Expand Up @@ -163,19 +163,5 @@ public async Task InitializeAsync(CancellationToken cancellationToken)
Logger.Error(ex, "Error on initialize Snyk service");
}
}

/// <summary>
/// Create new instance of SnykCli class with Options and Logger parameters.
/// </summary>
/// <returns>New SnykCli instance.</returns>
public ICli NewCli() => new SnykCli(this.Options, this.vsVersion);

private ICli _cli;
public ICli Cli {
get {
_cli ??= NewCli();
return _cli;
}
}
}
}
25 changes: 14 additions & 11 deletions Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ public async Task<FeaturesSettings> GetFeaturesSettingsAsync()
};
}

public void CancelDownloadTask()
{
this.CancelTask(downloadCliTokenSource);
}

private void CancelTask(CancellationTokenSource tokenSource)
{
try
Expand All @@ -709,7 +714,7 @@ private void CancelTask(CancellationTokenSource tokenSource)
}
catch (Exception e)
{
Logger.Error(e, "Try to cancel task");
Logger.Information(e, "Try to cancel task");
}
finally
{
Expand All @@ -728,14 +733,13 @@ public bool ShouldDownloadCli()
{
var currentCliVersion = userSettingsStorageService.GetCurrentCliVersion();

var lastCliReleaseDate = userSettingsStorageService.GetCliReleaseLastCheckDate();

var cliDownloader = new SnykCliDownloader(currentCliVersion);
var options = this.serviceProvider.Options;
var cliDownloader = new SnykCliDownloader(options, currentCliVersion);

var downloadPath = this.serviceProvider.Options.CliCustomPath;
var downloadPath = options.CliCustomPath;
var fileDestinationPath = GetCliFilePath(downloadPath);

return cliDownloader.IsCliDownloadNeeded(lastCliReleaseDate, fileDestinationPath);
return cliDownloader.IsCliDownloadNeeded(fileDestinationPath);

}
catch (Exception)
Expand All @@ -759,13 +763,13 @@ private async Task DownloadAsync(CliDownloadFinishedCallback downloadFinishedCal
this.isCliDownloading = true;
try
{
string currentCliVersion = userSettingsStorageService.GetCurrentCliVersion();
var currentCliVersion = userSettingsStorageService.GetCurrentCliVersion();

DateTime lastCliReleaseDate = userSettingsStorageService.GetCliReleaseLastCheckDate();
var lastCliReleaseDate = userSettingsStorageService.GetCliReleaseLastCheckDate();

var cliDownloader = new SnykCliDownloader(currentCliVersion);
var cliDownloader = new SnykCliDownloader(this.serviceProvider.Options, currentCliVersion);

List<CliDownloadFinishedCallback> downloadFinishedCallbacks = new List<CliDownloadFinishedCallback>();
var downloadFinishedCallbacks = new List<CliDownloadFinishedCallback>();

if (downloadFinishedCallback != null)
{
Expand All @@ -782,7 +786,6 @@ private async Task DownloadAsync(CliDownloadFinishedCallback downloadFinishedCal
var downloadPath = this.serviceProvider.Options.CliCustomPath;
await cliDownloader.AutoUpdateCliAsync(
progressWorker,
lastCliReleaseDate,
downloadPath,
downloadFinishedCallbacks: downloadFinishedCallbacks);
}
Expand Down
Loading
Loading