mirror of
https://github.com/yaakov-h/Shamir.git
synced 2025-01-18 16:56: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;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Storage.Blobs;
|
using Azure.Storage.Blobs;
|
||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Shamir.Console
|
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
|
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; }
|
public string? ConnectionString { get; set; }
|
||||||
|
|
||||||
[Value(0)]
|
[Option('a', "all", HelpText = "List all blobs in the container")]
|
||||||
public string? ContainerName { get; set; }
|
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>
|
public sealed class StorageLsCommand : ParsedArgumentsCommand<StorageLsOptions>
|
||||||
|
@ -55,7 +27,24 @@ namespace Shamir.Console
|
||||||
{
|
{
|
||||||
var connectionString = options.ConnectionString ?? Environment.GetEnvironmentVariable("AZURE_CONNECTION_STRING");
|
var connectionString = options.ConnectionString ?? Environment.GetEnvironmentVariable("AZURE_CONNECTION_STRING");
|
||||||
|
|
||||||
if (options.ContainerName is null)
|
if (options.Path is null)
|
||||||
|
{
|
||||||
|
if (options.EnumerateAll)
|
||||||
|
{
|
||||||
|
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);
|
var client = new BlobServiceClient(connectionString);
|
||||||
await foreach (var container in client.GetBlobContainersAsync())
|
await foreach (var container in client.GetBlobContainersAsync())
|
||||||
|
@ -63,17 +52,45 @@ namespace Shamir.Console
|
||||||
System.Console.WriteLine(container.Name);
|
System.Console.WriteLine(container.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else if (options.EnumerateAll)
|
||||||
{
|
{
|
||||||
var client = new BlobContainerClient(connectionString, options.ContainerName);
|
var containerName = options.Path;
|
||||||
|
var client = new BlobContainerClient(connectionString, containerName);
|
||||||
|
|
||||||
await foreach (var blob in client.GetBlobsAsync())
|
await foreach (var blob in client.GetBlobsAsync())
|
||||||
{
|
{
|
||||||
System.Console.Write(options.ContainerName);
|
System.Console.Write(containerName);
|
||||||
System.Console.Write('/');
|
System.Console.Write('/');
|
||||||
System.Console.WriteLine(blob.Name);
|
System.Console.WriteLine(blob.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var delimiterIndex = options.Path.IndexOf('/');
|
||||||
|
var containerName = delimiterIndex > 0 ? options.Path[..delimiterIndex] : options.Path;
|
||||||
|
var client = new BlobContainerClient(connectionString, containerName);
|
||||||
|
|
||||||
|
var prefix = delimiterIndex > 0 ? options.Path[(delimiterIndex + 1)..] : string.Empty;
|
||||||
|
await foreach (var blob in client.GetBlobsByHierarchyAsync(default, default, delimiter: "/", prefix))
|
||||||
|
{
|
||||||
|
System.Console.Write(containerName);
|
||||||
|
System.Console.Write('/');
|
||||||
|
|
||||||
|
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).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
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)
|
public static async Task<int> Main(string[] args)
|
||||||
{
|
{
|
||||||
await using var serviceProvider = new ServiceCollection()
|
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();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
var tree = new DefaultCommandTree(
|
var tree = new DefaultCommandTree(
|
||||||
|
|
Loading…
Reference in a new issue