Skip to content

Broadly adopt LibraryInstallationGoalState #794

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

Merged
merged 11 commits into from
Apr 23, 2025
19 changes: 7 additions & 12 deletions src/LibraryManager.Build/RestoreTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public override bool Execute()
return false;
}

IEnumerable<ILibraryOperationResult> validationResults = manifest.GetValidationResultsAsync(token).Result;
IEnumerable<OperationResult<LibraryInstallationGoalState>> validationResults = manifest.GetValidationResultsAsync(token).Result;
if (!validationResults.All(r => r.Success))
{
sw.Stop();
Expand All @@ -78,7 +78,7 @@ public override bool Execute()
return false;
}

IEnumerable<ILibraryOperationResult> results = manifest.RestoreAsync(token).Result;
IList<OperationResult<LibraryInstallationGoalState>> results = manifest.RestoreAsync(token).Result;

sw.Stop();
FlushLogger(logger);
Expand All @@ -103,7 +103,7 @@ private void FlushLogger(Logger logger)
}
}

private void LogResults(Stopwatch sw, IEnumerable<ILibraryOperationResult> results)
private void LogResults(Stopwatch sw, IEnumerable<OperationResult<LibraryInstallationGoalState>> results)
{
bool hasErrors = results.Any(r => !r.Success);

Expand Down Expand Up @@ -136,19 +136,14 @@ private void LogErrors(IEnumerable<IError> errors)
Log.LogMessage(MessageImportance.High, Environment.NewLine + text + Environment.NewLine);
}

private void PopulateFilesWritten(IEnumerable<ILibraryOperationResult> results, Dependencies dependencies)
private void PopulateFilesWritten(IEnumerable<OperationResult<LibraryInstallationGoalState>> results, Dependencies dependencies)
{
IEnumerable<ILibraryInstallationState> states = results.Where(r => r.Success).Select(r => r.InstallationState);
IEnumerable<LibraryInstallationGoalState> goalStates = results.Where(r => r.Success).Select(r => r.Result);
var list = new List<ITaskItem>();

foreach (ILibraryInstallationState state in states)
foreach (LibraryInstallationGoalState goalState in goalStates)
{
IProvider provider = dependencies.GetProvider(state.ProviderId);
OperationResult<LibraryInstallationGoalState> goalStateResult = provider.GetInstallationGoalStateAsync(state, CancellationToken.None).Result;
if (goalStateResult.Success)
{
list.AddRange(goalStateResult.Result.InstalledFiles.Select(f => new TaskItem(f.Key)));
}
list.AddRange(goalState.InstalledFiles.Select(f => new TaskItem(f.Key)));
}

FilesWritten = list.ToArray();
Expand Down
44 changes: 0 additions & 44 deletions src/LibraryManager.Contracts/ILibraryOperationResult.cs

This file was deleted.

13 changes: 3 additions & 10 deletions src/LibraryManager.Contracts/IProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -44,16 +45,8 @@ public interface IProvider
/// </summary>
/// <param name="desiredState">The details about the library to install.</param>
/// <param name="cancellationToken">A token that allows for the operation to be cancelled.</param>
/// <returns>The <see cref="ILibraryOperationResult"/> from the installation process.</returns>
Task<ILibraryOperationResult> InstallAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken);

/// <summary>
/// Updates library state using catalog if needed
/// </summary>
/// <param name="desiredState"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<ILibraryOperationResult> UpdateStateAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken);
/// <returns>The <see cref="OperationResult{LibraryInstallationGoalState}"/> from the installation process.</returns>
Task<OperationResult<LibraryInstallationGoalState>> InstallAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken);

/// <summary>
/// Gets the <see cref="ILibraryCatalog"/> for the <see cref="IProvider"/>. May be <code>null</code> if no catalog is supported.
Expand Down
2 changes: 1 addition & 1 deletion src/LibraryManager.Contracts/InvalidLibraryException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Microsoft.Web.LibraryManager.Contracts
/// For instance, if a <see cref="ILibraryInstallationState"/> with an id that isn't
/// recognized by the <see cref="IProvider"/> is being passed to <see cref="Contracts.IProvider.InstallAsync"/>,
/// this exception could be thrown so it can be handled inside <see cref="Contracts.IProvider.InstallAsync"/>
/// and an <see cref="IError"/> added to the <see cref="ILibraryOperationResult.Errors"/> collection.
/// and an <see cref="IError"/> added to the <see cref="OperationResult{LibraryInstallationGoalState}.Errors"/> collection.
/// </remarks>
[Serializable]
public class InvalidLibraryException : Exception
Expand Down
14 changes: 7 additions & 7 deletions src/LibraryManager.Vsix/Contracts/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static void LogEventsFooter(OperationType operationType, TimeSpan elapsed
/// <param name="operationType"></param>
/// <param name="elapsedTime"></param>
/// <param name="endOfMessage"></param>
public static void LogEventsSummary(IEnumerable<ILibraryOperationResult> totalResults, OperationType operationType, TimeSpan elapsedTime, bool endOfMessage = true)
public static void LogEventsSummary(IEnumerable<OperationResult<LibraryInstallationGoalState>> totalResults, OperationType operationType, TimeSpan elapsedTime, bool endOfMessage = true)
{
LogErrors(totalResults);
LogEvent(LogMessageGenerator.GetSummaryHeaderString(operationType), LogLevel.Task);
Expand Down Expand Up @@ -116,7 +116,7 @@ public static void LogErrorsSummary(IEnumerable<string> errorMessages, Operation
/// <param name="results">Operation results</param>
/// <param name="operationType"><see cref="OperationType"/></param>
/// <param name="endOfMessage">Whether or not to log end of message lines</param>
public static void LogErrorsSummary(IEnumerable<ILibraryOperationResult> results, OperationType operationType, bool endOfMessage = true)
public static void LogErrorsSummary(IEnumerable<OperationResult<LibraryInstallationGoalState>> results, OperationType operationType, bool endOfMessage = true)
{
List<string> errorStrings = GetErrorStrings(results);
LogErrorsSummary(errorStrings, operationType, endOfMessage);
Expand Down Expand Up @@ -271,7 +271,7 @@ private static bool EnsurePane()
return OutputWindowPaneValue != null;
}

private static void LogOperationSummary(IEnumerable<ILibraryOperationResult> totalResults, OperationType operation, TimeSpan elapsedTime)
private static void LogOperationSummary(IEnumerable<OperationResult<LibraryInstallationGoalState>> totalResults, OperationType operation, TimeSpan elapsedTime)
{
string messageText = LogMessageGenerator.GetOperationSummaryString(totalResults, operation, elapsedTime);

Expand All @@ -281,9 +281,9 @@ private static void LogOperationSummary(IEnumerable<ILibraryOperationResult> tot
}
}

private static void LogErrors(IEnumerable<ILibraryOperationResult> results)
private static void LogErrors(IEnumerable<OperationResult<LibraryInstallationGoalState>> results)
{
foreach (ILibraryOperationResult result in results)
foreach (OperationResult<LibraryInstallationGoalState> result in results)
{
foreach (IError error in result.Errors)
{
Expand All @@ -292,11 +292,11 @@ private static void LogErrors(IEnumerable<ILibraryOperationResult> results)
}
}

private static List<string> GetErrorStrings(IEnumerable<ILibraryOperationResult> results)
private static List<string> GetErrorStrings(IEnumerable<OperationResult<LibraryInstallationGoalState>> results)
{
List<string> errorStrings = new List<string>();

foreach (ILibraryOperationResult result in results)
foreach (OperationResult<LibraryInstallationGoalState> result in results)
{
foreach (IError error in result.Errors)
{
Expand Down
10 changes: 5 additions & 5 deletions src/LibraryManager.Vsix/ErrorList/ErrorListPropagator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ public ErrorListPropagator(string projectName, string configFileName)
public string ConfigFileName { get; set; }
public List<DisplayError> Errors { get; }

public bool HandleErrors(IEnumerable<ILibraryOperationResult> results)
public bool HandleErrors(IEnumerable<OperationResult<LibraryInstallationGoalState>> results)
{
string[] jsonLines = File.Exists(ConfigFileName) ? File.ReadLines(ConfigFileName).ToArray() : Array.Empty<string>();

foreach (ILibraryOperationResult result in results)
foreach (OperationResult<LibraryInstallationGoalState> goalStateResult in results)
{
if (!result.Success)
if (!goalStateResult.Success)
{
DisplayError[] displayErrors = result.Errors.Select(error => new DisplayError(error)).ToArray();
AddLineAndColumn(jsonLines, result.InstallationState, displayErrors);
DisplayError[] displayErrors = goalStateResult.Errors.Select(error => new DisplayError(error)).ToArray();
AddLineAndColumn(jsonLines, goalStateResult.Result?.InstallationState, displayErrors);

Errors.AddRange(displayErrors);
}
Expand Down
6 changes: 3 additions & 3 deletions src/LibraryManager.Vsix/Json/TextviewCreationListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void VsTextViewCreated(IVsTextView textViewAdapter)

_ = Task.Run(async () =>
{
IEnumerable<ILibraryOperationResult> results = await LibrariesValidator.GetManifestErrorsAsync(_manifest, dependencies, CancellationToken.None).ConfigureAwait(false);
IEnumerable<OperationResult<LibraryInstallationGoalState>> results = await LibrariesValidator.GetManifestErrorsAsync(_manifest, dependencies, CancellationToken.None).ConfigureAwait(false);
if (!results.All(r => r.Success))
{
AddErrorsToList(results);
Expand Down Expand Up @@ -108,7 +108,7 @@ async Task DoRestoreOnSaveAsync()
{
IDependencies dependencies = DependenciesFactory.FromConfigFile(textDocument.FilePath);
var newManifest = Manifest.FromJson(textDocument.TextBuffer.CurrentSnapshot.GetText(), dependencies);
IEnumerable<ILibraryOperationResult> results = await LibrariesValidator.GetManifestErrorsAsync(newManifest, dependencies, CancellationToken.None).ConfigureAwait(false);
IEnumerable<OperationResult<LibraryInstallationGoalState>> results = await LibrariesValidator.GetManifestErrorsAsync(newManifest, dependencies, CancellationToken.None).ConfigureAwait(false);

if (!results.All(r => r.Success))
{
Expand Down Expand Up @@ -170,7 +170,7 @@ private void OnViewClosed(object sender, EventArgs e)
_errorList?.ClearErrors();
}

private void AddErrorsToList(IEnumerable<ILibraryOperationResult> errors)
private void AddErrorsToList(IEnumerable<OperationResult<LibraryInstallationGoalState>> errors)
{
_errorList = new ErrorListPropagator(_project?.Name, _manifestPath);
_errorList.HandleErrors(errors);
Expand Down
32 changes: 15 additions & 17 deletions src/LibraryManager.Vsix/Shared/LibraryCommandService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ private async Task CleanLibrariesAsync(ProjectItem configProjectItem, Cancellati
Project project = VsHelpers.GetDTEProjectFromConfig(configFileName);

Manifest manifest = await Manifest.FromFileAsync(configFileName, dependencies, CancellationToken.None).ConfigureAwait(false);
IEnumerable<ILibraryOperationResult> results = new List<ILibraryOperationResult>();
IEnumerable<OperationResult<LibraryInstallationGoalState>> results = new List<OperationResult<LibraryInstallationGoalState>>();

if (manifest != null)
{
IEnumerable<ILibraryOperationResult> validationResults = await LibrariesValidator.GetManifestErrorsAsync(manifest, dependencies, cancellationToken).ConfigureAwait(false);
IEnumerable<OperationResult<LibraryInstallationGoalState>> validationResults = await LibrariesValidator.GetManifestErrorsAsync(manifest, dependencies, cancellationToken).ConfigureAwait(false);

if (!validationResults.All(r => r.Success))
{
Expand Down Expand Up @@ -234,7 +234,7 @@ private async Task RestoreInternalAsync(IDictionary<string, Manifest> manifests,

Logger.LogEvent(string.Format(LibraryManager.Resources.Text.Restore_LibrariesForProject, project?.Name), LogLevel.Operation);

IEnumerable<ILibraryOperationResult> validationResults = await LibrariesValidator.GetManifestErrorsAsync(manifest.Value, dependencies, cancellationToken).ConfigureAwait(false);
IEnumerable<OperationResult<LibraryInstallationGoalState>> validationResults = await LibrariesValidator.GetManifestErrorsAsync(manifest.Value, dependencies, cancellationToken).ConfigureAwait(false);
if (!validationResults.All(r => r.Success))
{
swLocal.Stop();
Expand All @@ -244,7 +244,7 @@ private async Task RestoreInternalAsync(IDictionary<string, Manifest> manifests,
}
else
{
IEnumerable<ILibraryOperationResult> results = await RestoreLibrariesAsync(manifest.Value, cancellationToken).ConfigureAwait(false);
var results = await RestoreLibrariesAsync(manifest.Value, cancellationToken).ConfigureAwait(false);
await AddFilesToProjectAsync(manifest.Key, project, results.Where(r =>r.Success && !r.UpToDate), cancellationToken).ConfigureAwait(false);

swLocal.Stop();
Expand All @@ -264,7 +264,7 @@ private async Task RestoreInternalAsync(IDictionary<string, Manifest> manifests,
}
}

private async Task<IEnumerable<ILibraryOperationResult>> RestoreLibrariesAsync(Manifest manifest, CancellationToken cancellationToken)
private async Task<IEnumerable<OperationResult<LibraryInstallationGoalState>>> RestoreLibrariesAsync(Manifest manifest, CancellationToken cancellationToken)
{
return await manifest.RestoreAsync(cancellationToken).ConfigureAwait(false);
}
Expand All @@ -281,11 +281,11 @@ private async Task UninstallLibraryAsync(string configFilePath, string libraryNa

var dependencies = _dependenciesFactory.FromConfigFile(configFilePath);
Manifest manifest = await Manifest.FromFileAsync(configFilePath, dependencies, cancellationToken).ConfigureAwait(false);
ILibraryOperationResult result = null;
OperationResult<LibraryInstallationGoalState> result = null;

if (manifest == null)
{
result = LibraryOperationResult.FromError(PredefinedErrors.ManifestMalformed());
result = OperationResult<LibraryInstallationGoalState>.FromError(PredefinedErrors.ManifestMalformed());
}
else
{
Expand All @@ -297,14 +297,14 @@ private async Task UninstallLibraryAsync(string configFilePath, string libraryNa

if (result.Errors.Any())
{
Logger.LogErrorsSummary(new List<ILibraryOperationResult> { result }, OperationType.Uninstall);
Logger.LogErrorsSummary(new List<OperationResult<LibraryInstallationGoalState>> { result }, OperationType.Uninstall);
}
else
{
Logger.LogEventsSummary(new List<ILibraryOperationResult> { result }, OperationType.Uninstall, sw.Elapsed);
Logger.LogEventsSummary(new List<OperationResult<LibraryInstallationGoalState>> { result }, OperationType.Uninstall, sw.Elapsed);
}

Telemetry.LogEventsSummary(new List<ILibraryOperationResult> { result }, OperationType.Uninstall, sw.Elapsed);
Telemetry.LogEventsSummary(new List<OperationResult<LibraryInstallationGoalState>> { result }, OperationType.Uninstall, sw.Elapsed);
}
catch (OperationCanceledException ex)
{
Expand Down Expand Up @@ -333,26 +333,24 @@ private string GetTaskTitle(OperationType operation, string libraryId)
return string.Empty;
}

private void AddErrorsToErrorList(string projectName, string configFile, IEnumerable<ILibraryOperationResult> results)
private void AddErrorsToErrorList(string projectName, string configFile, IEnumerable<OperationResult<LibraryInstallationGoalState>> results)
{
var errorList = new ErrorListPropagator(projectName, configFile);
errorList.HandleErrors(results);
}

private async Task AddFilesToProjectAsync(string configFilePath, Project project, IEnumerable<ILibraryOperationResult> results, CancellationToken cancellationToken)
private async Task AddFilesToProjectAsync(string configFilePath, Project project, IEnumerable<OperationResult<LibraryInstallationGoalState>> results, CancellationToken cancellationToken)
{
string workingDirectory = Path.GetDirectoryName(configFilePath);
var files = new List<string>();

if (project != null)
{
foreach (ILibraryOperationResult state in results)
foreach (OperationResult<LibraryInstallationGoalState> goalStateResult in results)
{
if (state.Success && !state.UpToDate && state.InstallationState.Files != null)
if (goalStateResult.Success && !goalStateResult.UpToDate && goalStateResult.Result.InstallationState.Files != null)
{
IEnumerable<string> absoluteFiles = state.InstallationState.Files
.Select(file => Path.Combine(workingDirectory, state.InstallationState.DestinationPath, file)
.Replace('/', Path.DirectorySeparatorChar));
IEnumerable<string> absoluteFiles = goalStateResult.Result.InstalledFiles.Keys;
files.AddRange(absoluteFiles);
}
}
Expand Down
Loading