implement "cdn ls" via CommandLineParser

This commit is contained in:
Yaakov 2021-09-26 00:07:48 +10:00
parent 74c7070e38
commit a4f9f13780
7 changed files with 113 additions and 8 deletions

View file

@ -26,6 +26,7 @@ namespace Shamir.Console
{ {
if (command.Name == args[0]) if (command.Name == args[0])
{ {
command.Initialize(args[1..]);
return command; return command;
} }
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -15,7 +16,11 @@ namespace Shamir.Console
public IImmutableStack<ICommandTree> Path { get; } public IImmutableStack<ICommandTree> Path { get; }
public ValueTask<int> ExecuteAsync() public void Initialize(ReadOnlySpan<string> args)
{
}
public ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider)
{ {
System.Console.Error.WriteLine(GetHelpText()); System.Console.Error.WriteLine(GetHelpText());
return ValueTask.FromResult(1); // TODO: const return ValueTask.FromResult(1); // TODO: const

View file

@ -1,9 +1,11 @@
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Shamir.Console namespace Shamir.Console
{ {
public interface ICommand : IOperationsNode public interface ICommand : IOperationsNode
{ {
ValueTask<int> ExecuteAsync(); void Initialize(ReadOnlySpan<string> args);
ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider);
} }
} }

View file

@ -0,0 +1,81 @@
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using CommandLine;
using Microsoft.Extensions.DependencyInjection;
namespace Shamir.Console
{
public abstract class ParsedArgumentsCommand<TOptions> : ICommand
{
public abstract string Name { get; }
public abstract string Description { get; }
public ImmutableArray<string> Arguments { get; private set; }
public void Initialize(ReadOnlySpan<string> args)
{
var array = ImmutableArray.CreateBuilder<string>(args.Length);
foreach (var arg in args)
{
array.Add(arg);
}
Arguments = array.MoveToImmutable();
}
public async ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider)
{
using var parser = serviceProvider.GetRequiredService<Parser>();
var result = parser.ParseArguments<TOptions>(Arguments);
return await result.MapResult(
options => ExecuteAsync(serviceProvider, options),
errors => ValueTask.FromResult(1)
);
}
public abstract ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider, TOptions options);
}
public class StorageLsOptions
{
[Option("connection-string", Required = false)]
public string? ConnectionString { get; set; }
[Value(0)]
public string? ContainerName { get; set; }
}
public sealed class StorageLsCommand : ParsedArgumentsCommand<StorageLsOptions>
{
public override string Name => "ls";
public override string Description => "List files in an Azure Storage account.";
public override async ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider, StorageLsOptions options)
{
var connectionString = options.ConnectionString ?? Environment.GetEnvironmentVariable("AZURE_CONNECTION_STRING");
if (options.ContainerName is null)
{
var client = new BlobServiceClient(connectionString);
await foreach (var container in client.GetBlobContainersAsync())
{
System.Console.WriteLine(container.Name);
}
}
else
{
var client = new BlobContainerClient(connectionString, options.ContainerName);
await foreach (var blob in client.GetBlobsAsync())
{
System.Console.Write(options.ContainerName);
System.Console.Write('/');
System.Console.WriteLine(blob.Name);
}
}
return 0;
}
}
}

View file

@ -1,5 +1,7 @@
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommandLine;
using Microsoft.Extensions.DependencyInjection;
namespace Shamir.Console namespace Shamir.Console
{ {
@ -7,19 +9,29 @@ namespace Shamir.Console
{ {
public static async Task<int> Main(string[] args) public static async Task<int> Main(string[] args)
{ {
await using var serviceProvider = new ServiceCollection()
.AddTransient<Parser>(sp => new Parser(with => with.EnableDashDash = true))
.BuildServiceProvider();
var tree = new DefaultCommandTree( var tree = new DefaultCommandTree(
"shamir", "shamir",
"command-line multitool", "command-line multitool",
ImmutableArray.Create<ICommandTree>( ImmutableArray.Create<ICommandTree>(
new DefaultCommandTree(
), "cdn",
"Browse and add new data to a CDN backed by Azure Storage",
ImmutableArray<ICommandTree>.Empty,
ImmutableArray.Create<ICommand>( ImmutableArray.Create<ICommand>(
new StorageLsCommand()
) ))
),
ImmutableArray<ICommand>.Empty
); );
var command = tree.FindCommand(args); var command = tree.FindCommand(args);
return await command.ExecuteAsync();
using var scope = serviceProvider.CreateScope();
return await command.ExecuteAsync(scope.ServiceProvider);
} }
} }
} }

View file

@ -9,7 +9,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.10.0" />
<PackageReference Include="CommandLineParser" Version="2.8.0" /> <PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -83,7 +83,9 @@ Commands:
public string Name { get; } public string Name { get; }
public string Description { get; } public string Description { get; }
public ValueTask<int> ExecuteAsync() => ValueTask.FromResult(0);
public void Initialize(ReadOnlySpan<string> args) { }
public ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider) => ValueTask.FromResult(0);
} }
} }
} }