public async Task <ILibraryInstallationResult> InstallAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken) { try { foreach (string file in desiredState.Files) { if (cancellationToken.IsCancellationRequested) { return(LibraryInstallationResult.FromCancelled(desiredState)); } string path = Path.Combine(desiredState.DestinationPath, file); var func = new Func <Stream>(() => GetStreamAsync(desiredState, file, cancellationToken).Result); bool writeOk = await HostInteraction.WriteFileAsync(path, func, desiredState, cancellationToken).ConfigureAwait(false); if (!writeOk) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.CouldNotWriteFile(file))); } } } catch (Exception ex) when(ex is InvalidLibraryException || ex.InnerException is InvalidLibraryException) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnableToResolveSource(desiredState.LibraryId, desiredState.ProviderId))); } catch (Exception ex) { HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error); return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnknownException())); } return(LibraryInstallationResult.FromSuccess(desiredState)); }
/// <summary> /// Updates file set on the passed in ILibraryInstallationState in case user selected to have all files included /// </summary> /// <param name="desiredState"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task <ILibraryOperationResult> UpdateStateAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(LibraryOperationResult.FromCancelled(desiredState)); } string libraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId(desiredState.Name, desiredState.Version, Id); try { ILibraryCatalog catalog = GetCatalog(); ILibrary library = await catalog.GetLibraryAsync(desiredState.Name, desiredState.Version, cancellationToken).ConfigureAwait(false); if (library == null) { return(new LibraryOperationResult(desiredState, PredefinedErrors.UnableToResolveSource(desiredState.Name, desiredState.ProviderId))); } if (desiredState.Files != null && desiredState.Files.Count > 0) { IReadOnlyList <string> invalidFiles = library.GetInvalidFiles(desiredState.Files); if (invalidFiles.Any()) { IError invalidFilesError = PredefinedErrors.InvalidFilesInLibrary(libraryId, invalidFiles, library.Files.Keys); return(new LibraryOperationResult(desiredState, invalidFilesError)); } else { return(LibraryOperationResult.FromSuccess(desiredState)); } } desiredState = new LibraryInstallationState { ProviderId = Id, Name = desiredState.Name, Version = desiredState.Version, DestinationPath = desiredState.DestinationPath, Files = library.Files.Keys.ToList(), IsUsingDefaultDestination = desiredState.IsUsingDefaultDestination, IsUsingDefaultProvider = desiredState.IsUsingDefaultProvider }; } catch (InvalidLibraryException) { return(new LibraryOperationResult(desiredState, PredefinedErrors.UnableToResolveSource(libraryId, desiredState.ProviderId))); } catch (UnauthorizedAccessException) { return(new LibraryOperationResult(desiredState, PredefinedErrors.PathOutsideWorkingDirectory())); } catch (Exception ex) { HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error); return(new LibraryOperationResult(desiredState, PredefinedErrors.UnknownException())); } return(LibraryOperationResult.FromSuccess(desiredState)); }
public void Predefined() { TestError(PredefinedErrors.UnknownException(), "LIB000"); TestError(PredefinedErrors.ProviderUnknown("_prov_"), "LIB001", "_prov_"); TestError(PredefinedErrors.UnableToResolveSource("_libid_", "_prov_"), "LIB002", "_libid_", "_prov_"); TestError(PredefinedErrors.CouldNotWriteFile("file.js"), "LIB003", "file.js"); TestError(PredefinedErrors.ManifestMalformed(), "LIB004"); }
private async Task <(string libraryId, ILibrary library)> ValidateLibraryExistsInCatalogAsync(CancellationToken cancellationToken) { try { ILibrary libraryToInstall = await ProviderCatalog.GetLibraryAsync(LibraryId.Value, cancellationToken); if (libraryToInstall != null) { return(LibraryId.Value, libraryToInstall); } } catch { // The library id wasn't in the exact format. } IReadOnlyList <ILibraryGroup> libraryGroup = await ProviderCatalog.SearchAsync(LibraryId.Value, 5, cancellationToken); IError invalidLibraryError = PredefinedErrors.UnableToResolveSource(LibraryId.Value, ProviderId); if (libraryGroup.Count == 0) { throw new InvalidOperationException($"[{invalidLibraryError.Code}]: {invalidLibraryError.Message}"); } var sb = new StringBuilder(); foreach (ILibraryGroup libGroup in libraryGroup) { IEnumerable <string> libIds = await libGroup.GetLibraryIdsAsync(cancellationToken); if (libIds == null || !libIds.Any()) { continue; } if (libGroup.DisplayName.Equals(LibraryId.Value, StringComparison.OrdinalIgnoreCase)) { // Found a group with an exact match. string latestVersion = await ProviderCatalog.GetLatestVersion(libIds.First(), false, cancellationToken); string libraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId(libGroup.DisplayName, latestVersion, ProviderId); ILibrary libraryToInstall = await ProviderCatalog.GetLibraryAsync(libraryId, cancellationToken); return(libraryId, libraryToInstall); } sb.AppendLine(" " + libIds.First()); } sb.Insert(0, $"[{invalidLibraryError.Code}]: {invalidLibraryError.Message} {Environment.NewLine} {Resources.SuggestedIdsMessage}{Environment.NewLine}"); throw new InvalidOperationException(sb.ToString()); }
/// <summary> /// Updates file set on the passed in ILibraryInstallationState in case user selected to have all files included /// </summary> /// <param name="desiredState"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task <ILibraryInstallationResult> UpdateStateAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(LibraryInstallationResult.FromCancelled(desiredState)); } try { ILibraryCatalog catalog = GetCatalog(); ILibrary library = await catalog.GetLibraryAsync(desiredState.LibraryId, cancellationToken).ConfigureAwait(false); if (library == null) { throw new InvalidLibraryException(desiredState.LibraryId, Id); } await HydrateCacheAsync(library, cancellationToken).ConfigureAwait(false); if (desiredState.Files != null && desiredState.Files.Count > 0) { return(LibraryInstallationResult.FromSuccess(desiredState)); } desiredState = new LibraryInstallationState { ProviderId = Id, LibraryId = desiredState.LibraryId, DestinationPath = desiredState.DestinationPath, Files = library.Files.Keys.ToList(), }; } catch (Exception ex) when(ex is InvalidLibraryException || ex.InnerException is InvalidLibraryException) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnableToResolveSource(desiredState.LibraryId, desiredState.ProviderId))); } catch (UnauthorizedAccessException) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.PathOutsideWorkingDirectory())); } catch (Exception ex) { HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error); return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnknownException())); } return(LibraryInstallationResult.FromSuccess(desiredState)); }
/// <summary> /// Validates <see cref="ILibraryInstallationState"/> /// </summary> /// <param name="state">The <see cref="ILibraryInstallationState"/> to validate.</param> /// <param name="provider">The <see cref="IProvider"/> used to validate <see cref="ILibraryInstallationState"/></param> /// <returns><see cref="ILibraryOperationResult"/> with the result of the validation</returns> public static async Task <ILibraryOperationResult> IsValidAsync(this ILibraryInstallationState state, IProvider provider) { if (state == null) { return(new LibraryOperationResult(state, new[] { PredefinedErrors.UnknownError() })); } if (provider == null) { return(new LibraryOperationResult(state, new[] { PredefinedErrors.ProviderUnknown(provider.Id) })); } if (string.IsNullOrEmpty(state.Name)) { return(new LibraryOperationResult(state, new[] { PredefinedErrors.LibraryIdIsUndefined() })); } ILibraryCatalog catalog = provider.GetCatalog(); try { await catalog.GetLibraryAsync(state.Name, state.Version, CancellationToken.None).ConfigureAwait(false); } catch { return(new LibraryOperationResult(state, new[] { PredefinedErrors.UnableToResolveSource(state.Name, state.Version, provider.Id) })); } if (string.IsNullOrEmpty(state.DestinationPath)) { return(new LibraryOperationResult(state, new[] { PredefinedErrors.PathIsUndefined() })); } if (state.DestinationPath.IndexOfAny(Path.GetInvalidPathChars()) >= 0) { return(new LibraryOperationResult(state, new[] { PredefinedErrors.DestinationPathHasInvalidCharacters(state.DestinationPath) })); } return(LibraryOperationResult.FromSuccess(state)); }
/// <inheritdoc /> public virtual async Task <ILibraryOperationResult> UpdateStateAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(LibraryOperationResult.FromCancelled(desiredState)); } string libraryId = LibraryNamingScheme.GetLibraryId(desiredState.Name, desiredState.Version); try { ILibraryCatalog catalog = GetCatalog(); ILibrary library = await catalog.GetLibraryAsync(desiredState.Name, desiredState.Version, cancellationToken).ConfigureAwait(false); if (library == null) { return(new LibraryOperationResult(desiredState, PredefinedErrors.UnableToResolveSource(desiredState.Name, desiredState.ProviderId))); } if (desiredState.Files != null && desiredState.Files.Count > 0) { // expand any potential file patterns IEnumerable <string> updatedFiles = FileGlobbingUtility.ExpandFileGlobs(desiredState.Files, library.Files.Keys); var processedState = new LibraryInstallationState { Name = desiredState.Name, Version = desiredState.Version, ProviderId = desiredState.ProviderId, DestinationPath = desiredState.DestinationPath, IsUsingDefaultDestination = desiredState.IsUsingDefaultDestination, IsUsingDefaultProvider = desiredState.IsUsingDefaultProvider, Files = updatedFiles.ToList(), }; return(CheckForInvalidFiles(processedState, libraryId, library)); } desiredState = new LibraryInstallationState { ProviderId = Id, Name = desiredState.Name, Version = desiredState.Version, DestinationPath = desiredState.DestinationPath, Files = library.Files.Keys.ToList(), IsUsingDefaultDestination = desiredState.IsUsingDefaultDestination, IsUsingDefaultProvider = desiredState.IsUsingDefaultProvider }; } catch (InvalidLibraryException) { return(new LibraryOperationResult(desiredState, PredefinedErrors.UnableToResolveSource(libraryId, desiredState.ProviderId))); } catch (UnauthorizedAccessException) { return(new LibraryOperationResult(desiredState, PredefinedErrors.PathOutsideWorkingDirectory())); } catch (Exception ex) { HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error); return(new LibraryOperationResult(desiredState, PredefinedErrors.UnknownException())); } return(LibraryOperationResult.FromSuccess(desiredState)); }
/// <summary> /// Installs a library as specified in the <paramref name="desiredState" /> parameter. /// </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="T:Microsoft.Web.LibraryInstaller.Contracts.ILibraryInstallationResult" /> from the installation process. /// </returns> /// <exception cref="InvalidLibraryException"></exception> public async Task <ILibraryInstallationResult> InstallAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(LibraryInstallationResult.FromCancelled(desiredState)); } if (!desiredState.IsValid(out IEnumerable <IError> errors)) { return(new LibraryInstallationResult(desiredState, errors.ToArray())); } try { var catalog = (CdnjsCatalog)GetCatalog(); ILibrary library = await catalog.GetLibraryAsync(desiredState.LibraryId, cancellationToken).ConfigureAwait(false); if (library == null) { throw new InvalidLibraryException(desiredState.LibraryId, Id); } await HydrateCacheAsync(library, cancellationToken).ConfigureAwait(false); var files = desiredState.Files?.ToList(); // "Files" is optional on this provider, so when none are specified all should be used if (files == null || files.Count == 0) { desiredState = new LibraryInstallationState { ProviderId = Id, LibraryId = desiredState.LibraryId, DestinationPath = desiredState.DestinationPath, Files = library.Files.Keys.ToList(), }; } foreach (string file in desiredState.Files) { if (cancellationToken.IsCancellationRequested) { return(LibraryInstallationResult.FromCancelled(desiredState)); } string path = Path.Combine(desiredState.DestinationPath, file); var sourceStream = new Func <Stream>(() => GetStreamAsync(desiredState, file, cancellationToken).Result); bool writeOk = await HostInteraction.WriteFileAsync(path, sourceStream, desiredState, cancellationToken).ConfigureAwait(false); if (!writeOk) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.CouldNotWriteFile(file))); } } } catch (Exception ex) when(ex is InvalidLibraryException || ex.InnerException is InvalidLibraryException) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnableToResolveSource(desiredState.LibraryId, desiredState.ProviderId))); } catch (UnauthorizedAccessException) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.PathOutsideWorkingDirectory())); } catch (Exception ex) { HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error); return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnknownException())); } return(LibraryInstallationResult.FromSuccess(desiredState)); }
public async Task <ILibraryInstallationResult> InstallAsync(ILibraryInstallationState desiredState, CancellationToken cancellationToken) { try { if (cancellationToken.IsCancellationRequested) { return(LibraryInstallationResult.FromCancelled(desiredState)); } var catalog = (CdnjsCatalog)GetCatalog(); ILibrary library = await catalog.GetLibraryAsync(desiredState.LibraryId, cancellationToken).ConfigureAwait(false); if (library == null) { throw new InvalidLibraryException(desiredState.LibraryId, Id); } await HydrateCacheAsync(library, cancellationToken).ConfigureAwait(false); var files = desiredState.Files?.ToList(); if (files == null || files.Count == 0) { desiredState = new LibraryInstallationState { ProviderId = Id, LibraryId = desiredState.LibraryId, DestinationPath = desiredState.DestinationPath, Files = library.Files.Keys.ToList() }; } foreach (string file in desiredState.Files) { if (cancellationToken.IsCancellationRequested) { return(LibraryInstallationResult.FromCancelled(desiredState)); } string path = Path.Combine(desiredState.DestinationPath, file); var func = new Func <Stream>(() => GetStream(desiredState, file)); bool writeOk = await HostInteraction.WriteFileAsync(path, func, desiredState, cancellationToken).ConfigureAwait(false); if (!writeOk) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.CouldNotWriteFile(file))); } } } catch (Exception ex) when(ex is InvalidLibraryException || ex.InnerException is InvalidLibraryException) { return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnableToResolveSource(desiredState.LibraryId, desiredState.ProviderId))); } catch (Exception ex) { HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error); return(new LibraryInstallationResult(desiredState, PredefinedErrors.UnknownException())); } return(LibraryInstallationResult.FromSuccess(desiredState)); }