public async Task InstallAsync_InvalidLibraryFiles() { var desiredState = new LibraryInstallationState { Name = "jquery", Version = "3.3.1", ProviderId = "unpkg", DestinationPath = "lib", Files = new[] { "file1.txt", "file2.txt" } }; // Install library ILibraryOperationResult result = await _provider.InstallAsync(desiredState, CancellationToken.None).ConfigureAwait(false); Assert.IsFalse(result.Success); Assert.AreEqual("LIB018", result.Errors[0].Code); }
public async Task InstallAsync_WithGlobPatterns_CorrectlyInstallsAllMatchingFiles() { var desiredState = new LibraryInstallationState { Name = "jquery", Version = "1.2.3", DestinationPath = "lib", Files = new[] { "*.js", "!*.min.js" }, }; // Install library ILibraryOperationResult result = await _provider.InstallAsync(desiredState, CancellationToken.None).ConfigureAwait(false); Assert.IsTrue(result.Success); Assert.IsTrue(result.InstallationState.Files.Count == 1); // jquery.min.js file was excluded Assert.AreEqual("jquery.js", result.InstallationState.Files.First()); }
public async Task InstallAsync_NoPathDefined() { var desiredState = new LibraryInstallationState { ProviderId = "unpkg", Name = "jquery", Version = "3.3.1" }; // Install library ILibraryOperationResult result = await _provider.InstallAsync(desiredState, CancellationToken.None).ConfigureAwait(false); Assert.IsFalse(result.Success); // Unknown exception. We no longer validate ILibraryState at the provider level Assert.AreEqual("LIB000", result.Errors[0].Code); }
protected async override Task <int> ExecuteInternalAsync() { Manifest manifest = await GetManifestAsync(); IEnumerable <ILibraryInstallationState> installedLibraries = ValidateParametersAndGetLibrariesToUninstall(manifest); if (installedLibraries == null || !installedLibraries.Any()) { Logger.Log(string.Format(Resources.Text.NoLibraryToUninstall, LibraryId.Value), LogLevel.Operation); return(0); } ILibraryInstallationState libraryToUninstall = null; if (installedLibraries.Count() > 1) { Logger.Log(string.Format(Resources.Text.MoreThanOneLibraryFoundToUninstall, LibraryId.Value), LogLevel.Operation); libraryToUninstall = LibraryResolver.ResolveLibraryByUserChoice(installedLibraries, HostEnvironment); } else { libraryToUninstall = installedLibraries.First(); } Task <bool> deleteFileAction(IEnumerable <string> s) => HostInteractions.DeleteFilesAsync(s, CancellationToken.None); ILibraryOperationResult result = await manifest.UninstallAsync(libraryToUninstall.LibraryId, deleteFileAction, CancellationToken.None); if (result.Success) { await manifest.SaveAsync(Settings.ManifestFileName, CancellationToken.None); Logger.Log(string.Format(Resources.Text.UninstalledLibrary, libraryToUninstall.LibraryId), LogLevel.Operation); } else { Logger.Log(string.Format(Resources.Text.UninstallFailed, libraryToUninstall.LibraryId), LogLevel.Error); foreach (IError error in result.Errors) { Logger.Log($"[{error.Code}]: {error.Message}", LogLevel.Error); } } return(0); }
public async Task InstallAsync_PathNotDefined() { IProvider provider = _dependencies.GetProvider("filesystem"); var desiredState = new LibraryInstallationState { ProviderId = "filesystem", Name = @"../file/does/not/exist.txt", Files = new[] { "file.js" } }; ILibraryOperationResult result = await provider.InstallAsync(desiredState, CancellationToken.None); Assert.IsFalse(result.Success); Assert.AreEqual(result.Errors.Count(), 1); Assert.AreEqual("LIB002", result.Errors[0].Code); }
public async Task IsValidAsync_State_HasUnknownLibraryFile() { var state = new Mocks.LibraryInstallationState { ProviderId = "unpkg", Name = "jquery", Version = "3.3.1", DestinationPath = "_path_", Files = new List<string>() { "a", "b" }, }; ILibraryOperationResult result = await state.IsValidAsync(_dependencies); // IsValidAsync does not validate library files // Issue https://github.com/aspnet/LibraryManager/issues/254 should fix that Assert.IsTrue(result.Success); }
public async Task IsValidAsync_State_HasNoProvider() { var state = new Mocks.LibraryInstallationState { Name = "_lib_", DestinationPath = "_path_", Files = new List <string>() { "a", "b" }, }; ILibraryOperationResult result = await state.IsValidAsync(_dependencies); Assert.IsFalse(result.Success); Assert.AreEqual(result.Errors.Count, 1); Assert.AreEqual(result.Errors.First().Code, "LIB007"); }
/// <summary> /// Installs a library with the given libraryId /// </summary> /// <param name="libraryId"></param> /// <param name="providerId"></param> /// <param name="files"></param> /// <param name="destination"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task <IEnumerable <ILibraryOperationResult> > InstallLibraryAsync(string libraryId, string providerId, IReadOnlyList <string> files, string destination, CancellationToken cancellationToken) { ILibraryOperationResult result; var desiredState = new LibraryInstallationState() { LibraryId = libraryId, Files = files, ProviderId = providerId, DestinationPath = destination }; UpdateLibraryProviderAndDestination(desiredState, DefaultProvider, DefaultDestination); ILibraryOperationResult validationResult = await desiredState.IsValidAsync(_dependencies); if (!validationResult.Success) { return(new [] { validationResult }); } IProvider provider = _dependencies.GetProvider(desiredState.ProviderId); if (provider == null) { return(new [] { new LibraryOperationResult(desiredState, new IError[] { PredefinedErrors.ProviderUnknown(desiredState.ProviderId) }) }); } IEnumerable <ILibraryOperationResult> conflictResults = await CheckLibraryForConflictsAsync(desiredState, cancellationToken).ConfigureAwait(false); if (!conflictResults.All(r => r.Success)) { return(conflictResults); } result = await provider.InstallAsync(desiredState, cancellationToken).ConfigureAwait(false); if (result.Success) { _libraries.Add(desiredState); } return(new [] { result }); }
private async Task UninstallLibraryAsync(string configFilePath, string libraryName, string version, string providerId, CancellationToken cancellationToken) { string libraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId(libraryName, version, providerId); Logger.LogEventsHeader(OperationType.Uninstall, libraryId); try { Stopwatch sw = new Stopwatch(); sw.Start(); var dependencies = _dependenciesFactory.FromConfigFile(configFilePath); Manifest manifest = await Manifest.FromFileAsync(configFilePath, dependencies, cancellationToken).ConfigureAwait(false); ILibraryOperationResult result = null; if (manifest == null) { result = LibraryOperationResult.FromError(PredefinedErrors.ManifestMalformed()); } else { IHostInteraction hostInteraction = dependencies.GetHostInteractions(); result = await manifest.UninstallAsync(libraryName, version, async (filesPaths) => await hostInteraction.DeleteFilesAsync(filesPaths, cancellationToken), cancellationToken).ConfigureAwait(false); } sw.Stop(); if (result.Errors.Any()) { Logger.LogErrorsSummary(new List<ILibraryOperationResult> { result }, OperationType.Uninstall); } else { Logger.LogEventsSummary(new List<ILibraryOperationResult> { result }, OperationType.Uninstall, sw.Elapsed); } Telemetry.LogEventsSummary(new List<ILibraryOperationResult> { result }, OperationType.Uninstall, sw.Elapsed); } catch (OperationCanceledException ex) { Logger.LogEvent(string.Format(LibraryManager.Resources.Text.Uninstall_LibraryCancelled, libraryId), LogLevel.Task); Telemetry.TrackException($@"{OperationType.Uninstall}Cancelled", ex); } }
private async Task <IEnumerable <FileIdentifier> > GetFilesWithVersionsAsync(ILibraryInstallationState state) { IEnumerable <FileIdentifier> filesWithVersions = new List <FileIdentifier>(); ILibraryCatalog catalog = _dependencies.GetProvider(state.ProviderId)?.GetCatalog(); if (catalog == null) { return(filesWithVersions); } ILibraryOperationResult validationResult = await state.IsValidAsync(_dependencies).ConfigureAwait(false); if (validationResult.Success) { IProvider provider = _dependencies.GetProvider(state.ProviderId); if (provider != null) { ILibraryOperationResult updatedStateResult = await provider.UpdateStateAsync(state, CancellationToken.None).ConfigureAwait(false); if (updatedStateResult.Success) { ILibrary library = await catalog.GetLibraryAsync(state.Name, state.Version, CancellationToken.None).ConfigureAwait(false); if (library != null && library.Files != null) { IEnumerable <string> desiredStateFiles = updatedStateResult.InstallationState.Files; if (desiredStateFiles != null && desiredStateFiles.Any()) { filesWithVersions = desiredStateFiles.Select(f => new FileIdentifier(Path.Combine(state.DestinationPath, f), library.Version)); } } } } } else { // Assert disabled due to breaking unit test execution. See: https://github.com/Microsoft/testfx/issues/561 //Debug.Assert(validationResult.Success); } return(filesWithVersions); }
public async Task IsValidAsync_State_FileSystem_LibraryIdHasInvalidPathCharacters() { var state = new Mocks.LibraryInstallationState { ProviderId = "filesystem", Name = "|lib_", DestinationPath = "_path_", Files = new List <string>() { "a", "b" }, }; ILibraryOperationResult result = await state.IsValidAsync(_dependencies); Assert.IsFalse(result.Success); Assert.AreEqual(result.Errors.Count, 1); Assert.AreEqual(result.Errors.First().Code, "LIB002"); }
public async Task InstallAsync_UriImage() { IProvider provider = _dependencies.GetProvider("filesystem"); var desiredState = new LibraryInstallationState { ProviderId = "filesystem", LibraryId = "http://glyphlist.azurewebsites.net/img/images/Flag.png", DestinationPath = "lib", Files = new[] { "Flag.png" } }; ILibraryOperationResult result = await provider.InstallAsync(desiredState, CancellationToken.None); Assert.IsTrue(result.Success, "Didn't install"); string copiedFile = Path.Combine(_projectFolder, desiredState.DestinationPath, desiredState.Files[0]); Assert.IsTrue(File.Exists(copiedFile), "File wasn't copied"); }
public async Task InstallAsync_EmptyFilesArray() { var desiredState = new LibraryInstallationState { ProviderId = "cdnjs", LibraryId = "[email protected]", DestinationPath = "lib" }; // Install library ILibraryOperationResult result = await _provider.InstallAsync(desiredState, CancellationToken.None).ConfigureAwait(false); Assert.IsTrue(result.Success); foreach (string file in new[] { "jquery.js", "jquery.min.js" }) { string absolute = Path.Combine(_projectFolder, desiredState.DestinationPath, file); Assert.IsTrue(File.Exists(absolute)); } }
public async Task <bool> IsLibraryInstallationStateValidAsync() { if (!LibraryIdToNameAndVersionConverter.Instance.IsWellFormedLibraryId(LibraryId, SelectedProvider.Id)) { ErrorMessage = string.Format(Text.BadLibraryId, LibraryId, SelectedProvider.Id, SelectedProvider.LibraryIdHintText); return(false); } (string name, string version) = LibraryIdToNameAndVersionConverter.Instance.GetLibraryNameAndVersion(LibraryId, SelectedProvider.Id); LibraryInstallationState libraryInstallationState = new LibraryInstallationState { Name = name, Version = version, ProviderId = SelectedProvider.Id, DestinationPath = TargetLocationViewModel.SearchText, Files = SelectedFiles?.ToList() }; ILibraryOperationResult libraryOperationResult = await libraryInstallationState.IsValidAsync(SelectedProvider).ConfigureAwait(false); IList <IError> errors = libraryOperationResult.Errors; ErrorMessage = string.Empty; if (errors != null && errors.Count > 0) { ErrorMessage = errors[0].Message; return(false); } AnyFileSelected = IsAnyFileSelected(DisplayRoots); if (!AnyFileSelected) { ErrorMessage = Text.NoFilesSelected; return(false); } return(true); }
/// <summary> /// Validates the values of each Library property and returns a collection of ILibraryOperationResult for each of them /// </summary> /// <param name="libraries"></param> /// <param name="dependencies"></param> /// <param name="cancellationToken"></param> /// <returns></returns> private static async Task <IEnumerable <ILibraryOperationResult> > ValidatePropertiesAsync(IEnumerable <ILibraryInstallationState> libraries, IDependencies dependencies, CancellationToken cancellationToken) { var validationStatus = new List <ILibraryOperationResult>(); foreach (ILibraryInstallationState library in libraries) { cancellationToken.ThrowIfCancellationRequested(); ILibraryOperationResult result = await library.IsValidAsync(dependencies).ConfigureAwait(false); if (!result.Success) { validationStatus.Add(result); } else { validationStatus.Add(LibraryOperationResult.FromSuccess(library)); } } return(validationStatus); }
/// <summary> /// Returns a collection of <see cref="ILibraryOperationResult"/> that represents the status for validation of each /// library /// </summary> /// <param name="libraries">Set of libraries to be validated</param> /// <param name="dependencies"><see cref="IDependencies"/>used to validate the libraries</param> /// <param name="defaultDestination">Default destination used to validate the libraries</param> /// <param name="defaultProvider">DefaultProvider used to validate the libraries</param> /// <param name="cancellationToken"></param> /// <returns></returns> public static async Task <IEnumerable <ILibraryOperationResult> > GetLibrariesErrorsAsync( IEnumerable <ILibraryInstallationState> libraries, IDependencies dependencies, string defaultDestination, string defaultProvider, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // Check for valid libraries IEnumerable <ILibraryOperationResult> validateLibraries = await ValidatePropertiesAsync(libraries, dependencies, cancellationToken).ConfigureAwait(false); if (!validateLibraries.All(t => t.Success)) { return(validateLibraries); } // Check for duplicate libraries IEnumerable <ILibraryOperationResult> duplicateLibraries = GetDuplicateLibrariesErrors(libraries); if (!duplicateLibraries.All(t => t.Success)) { return(duplicateLibraries); } // Check for files conflicts IEnumerable <ILibraryOperationResult> expandLibraries = await ExpandLibrariesAsync(libraries, dependencies, defaultDestination, defaultProvider, cancellationToken).ConfigureAwait(false); if (!expandLibraries.All(t => t.Success)) { return(expandLibraries); } libraries = expandLibraries.Select(l => l.InstallationState); IEnumerable <FileConflict> fileConflicts = GetFilesConflicts(libraries); ILibraryOperationResult conflictErrors = GetConflictErrors(fileConflicts); return(new[] { conflictErrors }); }
public async Task InstallAsync_RelativeFolderFiles() { string folder = Path.Combine(Path.GetTempPath(), "LibraryManager_test\\"); Directory.CreateDirectory(folder); File.WriteAllText(Path.Combine(folder, "file1.js"), ""); File.WriteAllText(Path.Combine(folder, "file2.js"), ""); File.WriteAllText(Path.Combine(folder, "file3.js"), ""); var origin = new Uri(folder, UriKind.Absolute); var current = new Uri(_projectFolder, UriKind.Absolute); Uri relativeFolder = current.MakeRelativeUri(origin); IProvider provider = _dependencies.GetProvider("filesystem"); var desiredState = new LibraryInstallationState { ProviderId = "filesystem", LibraryId = relativeFolder.OriginalString, DestinationPath = "lib", Files = new[] { "file1.js", "file2.js" } }; ILibraryOperationResult result = await provider.InstallAsync(desiredState, CancellationToken.None); Assert.IsTrue(result.Success, "Didn't install"); string file1 = Path.Combine(_projectFolder, desiredState.DestinationPath, desiredState.Files[0]); string file2 = Path.Combine(_projectFolder, desiredState.DestinationPath, desiredState.Files[1]); Assert.IsTrue(File.Exists(file1), "File1 wasn't copied"); Assert.IsTrue(File.Exists(file2), "File1 wasn't copied"); Assert.IsFalse(result.Cancelled); Assert.AreSame(desiredState, result.InstallationState); Assert.AreEqual(0, result.Errors.Count); }
/// <summary> /// Uninstalls the specified library and removes it from the <see cref="Libraries"/> collection. /// </summary> /// <param name="libraryName">Name of the library.</param> /// <param name="version">Version of the library to uninstall.</param> /// <param name="deleteFilesFunction"></param> /// <param name="cancellationToken"></param> public async Task <ILibraryOperationResult> UninstallAsync(string libraryName, string version, Func <IEnumerable <string>, Task <bool> > deleteFilesFunction, CancellationToken cancellationToken) { ILibraryInstallationState library = Libraries.FirstOrDefault(l => l.Name == libraryName && l.Version == version); if (cancellationToken.IsCancellationRequested) { return(LibraryOperationResult.FromCancelled(library)); } if (library != null) { ILibraryOperationResult validationResult = await library.IsValidAsync(_dependencies); if (!validationResult.Success) { return(validationResult); } try { ILibraryOperationResult result = await DeleteLibraryFilesAsync(library, deleteFilesFunction, cancellationToken).ConfigureAwait(false); if (result.Success) { _libraries.Remove(library); return(result); } } catch (OperationCanceledException) { return(LibraryOperationResult.FromCancelled(library)); } } return(LibraryOperationResult.FromError(PredefinedErrors.CouldNotDeleteLibrary(libraryName))); }
private async Task UninstallLibraryAsync(string configFilePath, string libraryId, CancellationToken cancellationToken) { Logger.LogEventsHeader(OperationType.Uninstall, libraryId); try { Stopwatch sw = new Stopwatch(); sw.Start(); var dependencies = Dependencies.FromConfigFile(configFilePath); Manifest manifest = await Manifest.FromFileAsync(configFilePath, dependencies, cancellationToken).ConfigureAwait(false); ILibraryOperationResult result = null; if (manifest == null) { result = LibraryOperationResult.FromError(PredefinedErrors.ManifestMalformed()); } else { IHostInteraction hostInteraction = dependencies.GetHostInteractions(); result = await manifest.UninstallAsync(libraryId, async (filesPaths) => await hostInteraction.DeleteFilesAsync(filesPaths, cancellationToken), cancellationToken).ConfigureAwait(false); } sw.Stop(); Logger.LogEventsSummary(new List <ILibraryOperationResult> { result }, OperationType.Uninstall, sw.Elapsed); Telemetry.TrackUserTask("libraryuninstall"); } catch (OperationCanceledException) { Logger.LogEvent(string.Format(LibraryManager.Resources.Text.Uninstall_LibraryCancelled, libraryId), LogLevel.Task); } }
protected override async Task <int> ExecuteInternalAsync() { Manifest manifest = await GetManifestAsync(); IEnumerable <ILibraryInstallationState> installedLibraries = ValidateParametersAndGetLibrariesToUpdate(manifest); if (installedLibraries == null || !installedLibraries.Any()) { Logger.Log(string.Format(Resources.NoLibraryFoundToUpdate, LibraryName.Value), LogLevel.Operation); return(0); } ILibraryInstallationState libraryToUpdate = null; if (installedLibraries.Count() > 1) { Logger.Log(string.Format(Resources.MoreThanOneLibraryFoundToUpdate, LibraryName.Value), LogLevel.Operation); libraryToUpdate = LibraryResolver.ResolveLibraryByUserChoice(installedLibraries, HostEnvironment); } else { libraryToUpdate = installedLibraries.First(); } string newLibraryId = null; if (ToVersion.HasValue()) { newLibraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId(libraryToUpdate.Name, ToVersion.Value(), libraryToUpdate.ProviderId); } else { string latestVersion = await GetLatestVersionAsync(libraryToUpdate, CancellationToken.None); if (!string.IsNullOrEmpty(latestVersion)) { newLibraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId(libraryToUpdate.Name, latestVersion, libraryToUpdate.ProviderId); } } if (newLibraryId == null || newLibraryId == libraryToUpdate.LibraryId) { Logger.Log(string.Format(Resources.LatestVersionAlreadyInstalled, libraryToUpdate.LibraryId), LogLevel.Operation); return(0); } Manifest backup = manifest.Clone(); string oldLibraryName = libraryToUpdate.Name; manifest.ReplaceLibraryId(libraryToUpdate, newLibraryId); // Delete files from old version of the library. await backup.RemoveUnwantedFilesAsync(manifest, CancellationToken.None); IEnumerable <ILibraryOperationResult> results = await manifest.RestoreAsync(CancellationToken.None); ILibraryOperationResult result = null; foreach (ILibraryOperationResult r in results) { if (!r.Success && r.Errors.Any(e => e.Message.Contains(libraryToUpdate.LibraryId))) { result = r; break; } else if (r.Success && r.InstallationState.LibraryId == libraryToUpdate.LibraryId && r.InstallationState.ProviderId == libraryToUpdate.ProviderId && r.InstallationState.DestinationPath == libraryToUpdate.DestinationPath) { result = r; break; } } if (result.Success) { await manifest.SaveAsync(HostEnvironment.EnvironmentSettings.ManifestFileName, CancellationToken.None); Logger.Log(string.Format(Resources.LibraryUpdated, oldLibraryName, newLibraryId), LogLevel.Operation); } else if (result.Errors != null) { if (ToVersion.HasValue()) { Logger.Log(string.Format(Resources.UpdateLibraryFailed, oldLibraryName, ToVersion.Value()), LogLevel.Error); } else { Logger.Log(string.Format(Resources.UpdateLibraryToLatestFailed, oldLibraryName), LogLevel.Error); } foreach (IError error in result.Errors) { Logger.Log(string.Format("[{0}]: {1}", error.Code, error.Message), LogLevel.Error); } } return(0); }
public async Task InstallAsync_FullEndToEnd() { ILibraryCatalog catalog = _provider.GetCatalog(); // Search for libraries to display in search result IReadOnlyList <ILibraryGroup> groups = await catalog.SearchAsync("jquery", 4, CancellationToken.None); Assert.IsTrue(groups.Count > 0); // Show details for selected library ILibraryGroup group = groups.FirstOrDefault(); Assert.AreEqual("jquery", group.DisplayName); // Get all libraries in group to display version list IEnumerable <string> libraryVersions = await group.GetLibraryVersions(CancellationToken.None); Assert.IsTrue(libraryVersions.Count() >= 0); // Get the library to install ILibrary library = await catalog.GetLibraryAsync("jquery", libraryVersions.First(), CancellationToken.None); Assert.AreEqual(group.DisplayName, library.Name); var desiredState = new LibraryInstallationState { Name = "jquery", Version = "3.3.1", ProviderId = "jsdelivr", DestinationPath = "lib", Files = new[] { "dist/jquery.js", "dist/jquery.min.js" } }; // Install library ILibraryOperationResult result = await _provider.InstallAsync(desiredState, CancellationToken.None).ConfigureAwait(false); foreach (string file in desiredState.Files) { string absolute = Path.Combine(_projectFolder, desiredState.DestinationPath, file); Assert.IsTrue(File.Exists(absolute)); } //GitHub library test Assert.IsTrue(result.Success); Assert.IsFalse(result.Cancelled); Assert.AreSame(desiredState, result.InstallationState); Assert.AreEqual(0, result.Errors.Count); var desiredStateGH = new LibraryInstallationState { Name = "jquery/jquery", Version = "3.3.1", ProviderId = "jsdelivr", DestinationPath = "lib", Files = new[] { "dist/jquery.js", "dist/jquery.min.js" } }; // Install library ILibraryOperationResult resultGH = await _provider.InstallAsync(desiredStateGH, CancellationToken.None).ConfigureAwait(false); foreach (string file in desiredStateGH.Files) { string absolute = Path.Combine(_projectFolder, desiredStateGH.DestinationPath, file); Assert.IsTrue(File.Exists(absolute)); } Assert.IsTrue(resultGH.Success); Assert.IsFalse(resultGH.Cancelled); Assert.AreSame(desiredStateGH, resultGH.InstallationState); Assert.AreEqual(0, resultGH.Errors.Count); }