// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixToolset.Core.ExtensionCache
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using WixToolset.Extensibility.Data;
using WixToolset.Extensibility.Services;
///
/// Extension cache manager command.
///
internal class ExtensionCacheManagerCommand : ICommandLineCommand
{
private enum CacheSubcommand
{
Add,
Remove,
List
}
public ExtensionCacheManagerCommand(IWixToolsetServiceProvider serviceProvider)
{
this.Messaging = serviceProvider.GetService();
this.ExtensionReferences = new List();
}
private IMessaging Messaging { get; }
public bool ShowLogo { get; private set; }
public bool StopParsing { get; private set; }
private bool ShowHelp { get; set; }
private bool Global { get; set; }
private CacheSubcommand? Subcommand { get; set; }
private List ExtensionReferences { get; }
public async Task ExecuteAsync(CancellationToken cancellationToken)
{
if (this.ShowHelp || !this.Subcommand.HasValue)
{
DisplayHelp();
return 1;
}
var success = false;
var cacheManager = new ExtensionCacheManager();
switch (this.Subcommand)
{
case CacheSubcommand.Add:
success = await this.AddExtensions(cacheManager, cancellationToken);
break;
case CacheSubcommand.Remove:
success = await this.RemoveExtensions(cacheManager, cancellationToken);
break;
case CacheSubcommand.List:
success = await this.ListExtensions(cacheManager, cancellationToken);
break;
}
return success ? 0 : 2;
}
public bool TryParseArgument(ICommandLineParser parser, string argument)
{
if (!parser.IsSwitch(argument))
{
if (!this.Subcommand.HasValue)
{
if (!Enum.TryParse(argument, true, out CacheSubcommand subcommand))
{
return false;
}
this.Subcommand = subcommand;
}
else
{
this.ExtensionReferences.Add(argument);
}
return true;
}
var parameter = argument.Substring(1);
switch (parameter.ToLowerInvariant())
{
case "?":
case "h":
case "-help":
this.ShowHelp = true;
this.ShowLogo = true;
this.StopParsing = true;
return true;
case "nologo":
case "-nologo":
this.ShowLogo = false;
return true;
case "g":
case "-global":
this.Global = true;
return true;
}
return false;
}
private async Task AddExtensions(ExtensionCacheManager cacheManager, CancellationToken cancellationToken)
{
var success = false;
foreach (var extensionRef in this.ExtensionReferences)
{
var added = await cacheManager.AddAsync(this.Global, extensionRef, cancellationToken);
success |= added;
}
return success;
}
private async Task RemoveExtensions(ExtensionCacheManager cacheManager, CancellationToken cancellationToken)
{
var success = false;
foreach (var extensionRef in this.ExtensionReferences)
{
var removed = await cacheManager.RemoveAsync(this.Global, extensionRef, cancellationToken);
success |= removed;
}
return success;
}
private async Task ListExtensions(ExtensionCacheManager cacheManager, CancellationToken cancellationToken)
{
var found = false;
var extensionRef = this.ExtensionReferences.FirstOrDefault();
var extensions = await cacheManager.ListAsync(this.Global, extensionRef, cancellationToken);
foreach (var extension in extensions)
{
this.Messaging.Write($"{extension.Id} {extension.Version}{(extension.Damaged ? " (damaged)" : String.Empty)}");
found = true;
}
return found;
}
private static void DisplayHelp()
{
Console.WriteLine();
Console.WriteLine("Usage: wix extension add|remove|list [extensionRef]");
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine(" -h|--help Show command line help.");
Console.WriteLine(" -g|--global Add/remove the extension for the current user.");
Console.WriteLine(" --nologo Suppress displaying the logo information.");
Console.WriteLine();
Console.WriteLine("Commands:");
Console.WriteLine();
Console.WriteLine(" add Add extension to the cache.");
Console.WriteLine(" list List extensions in the cache.");
Console.WriteLine(" remove Remove extension from the cache.");
Console.WriteLine();
Console.WriteLine(" extensionRef format: extensionId/version (the version is optional)");
}
}
}