mirror of
https://github.com/yaakov-h/Shamir.git
synced 2025-01-18 08:46:33 +00:00
Minor refactoring, add enumeration of storage container by folder, by container, or by entire account
This commit is contained in:
parent
a4f9f13780
commit
4743b1a74c
4 changed files with 123 additions and 43 deletions
40
src/console/CommandTree/ParsedArgumentsCommand.cs
Normal file
40
src/console/CommandTree/ParsedArgumentsCommand.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading.Tasks;
|
||||
using CommandLine;
|
||||
using CommandLine.Text;
|
||||
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)
|
||||
{
|
||||
Arguments = args.ToImmutableArray();
|
||||
}
|
||||
|
||||
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 =>
|
||||
{
|
||||
var helpText = HelpText.AutoBuild(result);
|
||||
helpText.Heading = string.Empty;
|
||||
helpText.Copyright = string.Empty;
|
||||
System.Console.Error.WriteLine(helpText);
|
||||
return ValueTask.FromResult(1);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public abstract ValueTask<int> ExecuteAsync(IServiceProvider serviceProvider, TOptions options);
|
||||
}
|
||||
}
|
|
@ -1,48 +1,20 @@
|
|||
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)]
|
||||
[Option("connection-string", Required = false, HelpText = "Azure Storage connection string for the Storage Account backing the CDN.")]
|
||||
public string? ConnectionString { get; set; }
|
||||
|
||||
[Value(0)]
|
||||
public string? ContainerName { get; set; }
|
||||
[Option('a', "all", HelpText = "List all blobs in the container")]
|
||||
public bool EnumerateAll { get; set; }
|
||||
|
||||
[Value(0, MetaName = "Path", HelpText = "Path to enumerate, starting with the Azure Storage container name.")]
|
||||
public string? Path { get; set; }
|
||||
}
|
||||
|
||||
public sealed class StorageLsCommand : ParsedArgumentsCommand<StorageLsOptions>
|
||||
|
@ -55,23 +27,68 @@ namespace Shamir.Console
|
|||
{
|
||||
var connectionString = options.ConnectionString ?? Environment.GetEnvironmentVariable("AZURE_CONNECTION_STRING");
|
||||
|
||||
if (options.ContainerName is null)
|
||||
if (options.Path is null)
|
||||
{
|
||||
var client = new BlobServiceClient(connectionString);
|
||||
await foreach (var container in client.GetBlobContainersAsync())
|
||||
if (options.EnumerateAll)
|
||||
{
|
||||
System.Console.WriteLine(container.Name);
|
||||
var client = new BlobServiceClient(connectionString);
|
||||
await foreach (var container in client.GetBlobContainersAsync())
|
||||
{
|
||||
var containerClient = new BlobContainerClient(connectionString, container.Name);
|
||||
|
||||
await foreach (var blob in containerClient.GetBlobsAsync())
|
||||
{
|
||||
System.Console.Write(container.Name);
|
||||
System.Console.Write('/');
|
||||
System.Console.WriteLine(blob.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var client = new BlobServiceClient(connectionString);
|
||||
await foreach (var container in client.GetBlobContainersAsync())
|
||||
{
|
||||
System.Console.WriteLine(container.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (options.EnumerateAll)
|
||||
{
|
||||
var containerName = options.Path;
|
||||
var client = new BlobContainerClient(connectionString, containerName);
|
||||
|
||||
await foreach (var blob in client.GetBlobsAsync())
|
||||
{
|
||||
System.Console.Write(containerName);
|
||||
System.Console.Write('/');
|
||||
System.Console.WriteLine(blob.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var client = new BlobContainerClient(connectionString, options.ContainerName);
|
||||
var delimiterIndex = options.Path.IndexOf('/');
|
||||
var containerName = delimiterIndex > 0 ? options.Path[..delimiterIndex] : options.Path;
|
||||
var client = new BlobContainerClient(connectionString, containerName);
|
||||
|
||||
await foreach (var blob in client.GetBlobsAsync())
|
||||
var prefix = delimiterIndex > 0 ? options.Path[(delimiterIndex + 1)..] : string.Empty;
|
||||
await foreach (var blob in client.GetBlobsByHierarchyAsync(default, default, delimiter: "/", prefix))
|
||||
{
|
||||
System.Console.Write(options.ContainerName);
|
||||
System.Console.Write(containerName);
|
||||
System.Console.Write('/');
|
||||
System.Console.WriteLine(blob.Name);
|
||||
|
||||
if (blob.IsPrefix)
|
||||
{
|
||||
System.Console.WriteLine(blob.Prefix);
|
||||
}
|
||||
else if (blob.IsBlob)
|
||||
{
|
||||
System.Console.WriteLine(blob.Blob.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("Unknown result - neither a blob nor a prefix (folder).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
src/console/Extensions/ImmutableArrayExtensions.cs
Normal file
17
src/console/Extensions/ImmutableArrayExtensions.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace System.Collections.Immutable
|
||||
{
|
||||
public static class ImmutableArrayExtensions
|
||||
{
|
||||
public static ImmutableArray<T> ToImmutableArray<T>(this ReadOnlySpan<T> span)
|
||||
{
|
||||
var array = ImmutableArray.CreateBuilder<T>(span.Length);
|
||||
|
||||
foreach (var value in span)
|
||||
{
|
||||
array.Add(value);
|
||||
}
|
||||
|
||||
return array.MoveToImmutable();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,13 @@ namespace Shamir.Console
|
|||
public static async Task<int> Main(string[] args)
|
||||
{
|
||||
await using var serviceProvider = new ServiceCollection()
|
||||
.AddTransient<Parser>(sp => new Parser(with => with.EnableDashDash = true))
|
||||
.AddTransient<Parser>(sp => new Parser(with =>
|
||||
{
|
||||
with.AutoHelp = true;
|
||||
with.AutoVersion = true;
|
||||
with.EnableDashDash = true;
|
||||
with.IgnoreUnknownArguments = false;
|
||||
}))
|
||||
.BuildServiceProvider();
|
||||
|
||||
var tree = new DefaultCommandTree(
|
||||
|
|
Loading…
Reference in a new issue