aspnetcore/src/Microsoft.HttpRepl/Commands/ListCommand.cs

181 lines
6.9 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.HttpRepl.Preferences;
using Microsoft.Repl;
using Microsoft.Repl.Commanding;
using Microsoft.Repl.Parsing;
namespace Microsoft.HttpRepl.Commands
{
public class ListCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
{
private const string RecursiveOption = nameof(RecursiveOption);
protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
{
if (programState.SwaggerEndpoint != null)
{
string swaggerRequeryBehaviorSetting = programState.GetStringPreference(WellKnownPreference.SwaggerRequeryBehavior, "auto");
if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
{
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
}
}
if (programState.Structure == null || programState.BaseAddress == null)
{
return;
}
string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;
//If it's an absolute URI, nothing to suggest
if (Uri.TryCreate(path, UriKind.Absolute, out Uri _))
{
return;
}
IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);
string thisDirMethod = s.RequestInfo != null && s.RequestInfo.Methods.Count > 0
? "[" + string.Join("|", s.RequestInfo.Methods) + "]"
: "[]";
List<TreeNode> roots = new List<TreeNode>();
Formatter formatter = new Formatter();
roots.Add(new TreeNode(formatter, ".", thisDirMethod));
if (s.Parent != null)
{
string parentDirMethod = s.Parent.RequestInfo != null && s.Parent.RequestInfo.Methods.Count > 0
? "[" + string.Join("|", s.Parent.RequestInfo.Methods) + "]"
: "[]";
roots.Add(new TreeNode(formatter, "..", parentDirMethod));
}
int recursionDepth = 1;
if (commandInput.Options[RecursiveOption].Count > 0)
{
if (string.IsNullOrEmpty(commandInput.Options[RecursiveOption][0]?.Text))
{
recursionDepth = int.MaxValue;
}
else if (int.TryParse(commandInput.Options[RecursiveOption][0].Text, NumberStyles.Integer, CultureInfo.InvariantCulture, out int rd) && rd > 1)
{
recursionDepth = rd;
}
}
foreach (string child in s.DirectoryNames)
{
IDirectoryStructure dir = s.GetChildDirectory(child);
string methods = dir.RequestInfo != null && dir.RequestInfo.Methods.Count > 0
? "[" + string.Join("|", dir.RequestInfo.Methods) + "]"
: "[]";
TreeNode dirNode = new TreeNode(formatter, child, methods);
roots.Add(dirNode);
Recurse(dirNode, dir, recursionDepth - 1);
}
foreach (TreeNode node in roots)
{
shellState.ConsoleManager.WriteLine(node.ToString());
}
}
private static void Recurse(TreeNode parentNode, IDirectoryStructure parent, int remainingDepth)
{
if (remainingDepth <= 0)
{
return;
}
foreach (string child in parent.DirectoryNames)
{
IDirectoryStructure dir = parent.GetChildDirectory(child);
string methods = dir.RequestInfo != null && dir.RequestInfo.Methods.Count > 0
? "[" + string.Join("|", dir.RequestInfo.Methods) + "]"
: "[]";
TreeNode node = parentNode.AddChild(child, methods);
Recurse(node, dir, remainingDepth - 1);
}
}
protected override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("ls").AlternateName("dir")
.MaximumArgCount(1)
.WithOption(new CommandOptionSpecification(RecursiveOption, maximumOccurrences: 1, acceptsValue: true, forms: new[] {"-r", "--recursive"}))
.Finish();
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
{
return "Lists the contents of a directory";
}
public override string GetHelpSummary(IShellState shellState, HttpState programState)
{
return "ls - Performs a directory listing";
}
protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)
{
if (programState.Structure == null || programState.BaseAddress == null)
{
return null;
}
//If it's an absolute URI, nothing to suggest
if (Uri.TryCreate(normalCompletionString, UriKind.Absolute, out Uri _))
{
return null;
}
string path = normalCompletionString.Replace('\\', '/');
int searchFrom = normalCompletionString.Length - 1;
int lastSlash = path.LastIndexOf('/', searchFrom);
string prefix;
if (lastSlash < 0)
{
path = string.Empty;
prefix = normalCompletionString;
}
else
{
path = path.Substring(0, lastSlash + 1);
prefix = normalCompletionString.Substring(lastSlash + 1);
}
IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);
List<string> results = new List<string>();
foreach (string child in s.DirectoryNames)
{
if (child.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
results.Add(path + child);
}
}
return results;
}
}
}