Merge pull request #510 from dotnet-maestro-bot/merge/release/2.2-to-master

[automated] Merge branch 'release/2.2' => 'master'
This commit is contained in:
Mike Lorbetske 2018-11-02 09:42:33 -07:00 committed by GitHub
commit 2af66e4eba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 94 additions and 52 deletions

View File

@ -7,6 +7,7 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -116,8 +117,18 @@ namespace Microsoft.HttpRepl.Commands
bool deleteFile = false; bool deleteFile = false;
noBody = commandInput.Options[NoBodyOption].Count > 0; noBody = commandInput.Options[NoBodyOption].Count > 0;
if (!thisRequestHeaders.TryGetValue("content-type", out string contentType) && programState.Headers.TryGetValue("content-type", out IEnumerable<string> contentTypes))
{
contentType = contentTypes.FirstOrDefault();
}
if (!noBody) if (!noBody)
{ {
if (string.IsNullOrEmpty(contentType))
{
contentType = "application/json";
}
if (commandInput.Options[BodyFileOption].Count > 0) if (commandInput.Options[BodyFileOption].Count > 0)
{ {
filePath = commandInput.Options[BodyFileOption][0].Text; filePath = commandInput.Options[BodyFileOption][0].Text;
@ -144,18 +155,7 @@ namespace Microsoft.HttpRepl.Commands
deleteFile = true; deleteFile = true;
filePath = Path.GetTempFileName(); filePath = Path.GetTempFileName();
if (!thisRequestHeaders.TryGetValue("content-type", out string contentType) && programState.Headers.TryGetValue("content-type", out IEnumerable<string> contentTypes)) string exampleBody = programState.GetExampleBody(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty, ref contentType, Verb);
{
contentType = contentTypes.FirstOrDefault();
}
if (contentType == null)
{
contentType = "application/json";
}
string exampleBody = programState.GetExampleBody(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty, contentType, Verb);
request.Headers.TryAddWithoutValidation("Content-Type", contentType);
if (!string.IsNullOrEmpty(exampleBody)) if (!string.IsNullOrEmpty(exampleBody))
{ {
@ -179,6 +179,11 @@ namespace Microsoft.HttpRepl.Commands
} }
} }
if (string.IsNullOrEmpty(contentType))
{
contentType = "application/json";
}
byte[] data = noBody byte[] data = noBody
? new byte[0] ? new byte[0]
: string.IsNullOrEmpty(bodyContent) : string.IsNullOrEmpty(bodyContent)
@ -186,6 +191,7 @@ namespace Microsoft.HttpRepl.Commands
: Encoding.UTF8.GetBytes(bodyContent); : Encoding.UTF8.GetBytes(bodyContent);
HttpContent content = new ByteArrayContent(data); HttpContent content = new ByteArrayContent(data);
content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
request.Content = content; request.Content = content;
if (deleteFile) if (deleteFile)

View File

@ -218,7 +218,7 @@ namespace Microsoft.HttpRepl.Commands
shellState.ConsoleManager.WriteLine($"{"HEAD",navCommandColumn}{"Issues a HEAD request."}"); shellState.ConsoleManager.WriteLine($"{"HEAD",navCommandColumn}{"Issues a HEAD request."}");
shellState.ConsoleManager.WriteLine($"{"OPTIONS",navCommandColumn}{"Issues an OPTIONS request."}"); shellState.ConsoleManager.WriteLine($"{"OPTIONS",navCommandColumn}{"Issues an OPTIONS request."}");
shellState.ConsoleManager.WriteLine(); shellState.ConsoleManager.WriteLine();
shellState.ConsoleManager.WriteLine($"{"set header",navCommandColumn}{"Sets or clears a header for all requests. e.g. `set header content-type:application/json`"}"); shellState.ConsoleManager.WriteLine($"{"set header",navCommandColumn}{"Sets or clears a header for all requests. e.g. `set header content-type application/json`"}");
shellState.ConsoleManager.WriteLine(); shellState.ConsoleManager.WriteLine();
shellState.ConsoleManager.WriteLine(); shellState.ConsoleManager.WriteLine();

View File

@ -53,7 +53,7 @@ namespace Microsoft.HttpRepl.Commands
catch { } catch { }
} }
if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "/swagger/v1/swagger.json", out Uri result)) if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "swagger.json", out Uri result))
{ {
state.SwaggerStructure = null; state.SwaggerStructure = null;
} }
@ -64,6 +64,21 @@ namespace Microsoft.HttpRepl.Commands
{ {
shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result); shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result);
} }
else
{
if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "swagger/v1/swagger.json", out result))
{
state.SwaggerStructure = null;
}
else
{
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, state, result, cancellationToken).ConfigureAwait(false);
if (state.SwaggerStructure != null)
{
shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result);
}
}
}
} }
} }

View File

@ -47,7 +47,7 @@ namespace Microsoft.HttpRepl.Commands
{ {
if (string.IsNullOrEmpty(parameterSetsByContentType.Key)) if (string.IsNullOrEmpty(parameterSetsByContentType.Key))
{ {
dirRequestInfo.SetFallbackRequestBody(method, GetBodyString(null, parameterSetsByContentType.Value)); dirRequestInfo.SetFallbackRequestBody(method, parameterSetsByContentType.Key, GetBodyString(null, parameterSetsByContentType.Value));
} }
dirRequestInfo.SetRequestBody(method, parameterSetsByContentType.Key, GetBodyString(parameterSetsByContentType.Key, parameterSetsByContentType.Value)); dirRequestInfo.SetRequestBody(method, parameterSetsByContentType.Key, GetBodyString(parameterSetsByContentType.Key, parameterSetsByContentType.Value));

View File

@ -55,13 +55,14 @@ namespace Microsoft.HttpRepl
private readonly HashSet<string> _methods = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private readonly HashSet<string> _methods = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, Dictionary<string, string>> _requestBodiesByMethodByContentType = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, Dictionary<string, string>> _requestBodiesByMethodByContentType = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string> _fallbackBodyStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, string> _fallbackBodyStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string> _fallbackContentTypeStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, IReadOnlyList<string>> _contentTypesByMethod = new Dictionary<string, IReadOnlyList<string>>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, IReadOnlyList<string>> _contentTypesByMethod = new Dictionary<string, IReadOnlyList<string>>(StringComparer.OrdinalIgnoreCase);
public IReadOnlyList<string> Methods => _methods.ToList(); public IReadOnlyList<string> Methods => _methods.ToList();
public IReadOnlyDictionary<string, IReadOnlyList<string>> ContentTypesByMethod => _contentTypesByMethod; public IReadOnlyDictionary<string, IReadOnlyList<string>> ContentTypesByMethod => _contentTypesByMethod;
public string GetRequestBodyForContentType(string contentType, string method) public string GetRequestBodyForContentType(ref string contentType, string method)
{ {
if (_requestBodiesByMethodByContentType.TryGetValue(method, out Dictionary<string, string> bodiesByContentType) if (_requestBodiesByMethodByContentType.TryGetValue(method, out Dictionary<string, string> bodiesByContentType)
&& bodiesByContentType.TryGetValue(contentType, out string body)) && bodiesByContentType.TryGetValue(contentType, out string body))
@ -71,6 +72,11 @@ namespace Microsoft.HttpRepl
if (_fallbackBodyStringsByMethod.TryGetValue(method, out body)) if (_fallbackBodyStringsByMethod.TryGetValue(method, out body))
{ {
if (_fallbackContentTypeStringsByMethod.TryGetValue(method, out string newContentType))
{
contentType = newContentType;
}
return body; return body;
} }
@ -100,9 +106,10 @@ namespace Microsoft.HttpRepl
_methods.Add(method); _methods.Add(method);
} }
public void SetFallbackRequestBody(string method, string fallbackBodyString) public void SetFallbackRequestBody(string method, string contentType, string fallbackBodyString)
{ {
_fallbackBodyStringsByMethod[method] = fallbackBodyString; _fallbackBodyStringsByMethod[method] = fallbackBodyString;
_fallbackContentTypeStringsByMethod[method] = contentType;
} }
} }
} }

View File

@ -148,12 +148,12 @@ namespace Microsoft.HttpRepl
} }
} }
public string GetExampleBody(string path, string contentType, string method) public string GetExampleBody(string path, ref string contentType, string method)
{ {
Uri effectivePath = GetEffectivePath(path); Uri effectivePath = GetEffectivePath(path);
string rootRelativePath = effectivePath.LocalPath.Substring(BaseAddress.LocalPath.Length).TrimStart('/'); string rootRelativePath = effectivePath.LocalPath.Substring(BaseAddress.LocalPath.Length).TrimStart('/');
IDirectoryStructure structure = SwaggerStructure?.TraverseTo(rootRelativePath); IDirectoryStructure structure = SwaggerStructure?.TraverseTo(rootRelativePath);
return structure?.RequestInfo?.GetRequestBodyForContentType(contentType, method); return structure?.RequestInfo?.GetRequestBodyForContentType(ref contentType, method);
} }
public IEnumerable<string> GetApplicableContentTypes(string method, string path) public IEnumerable<string> GetApplicableContentTypes(string method, string path)

View File

@ -11,6 +11,6 @@ namespace Microsoft.HttpRepl
IReadOnlyList<string> Methods { get; } IReadOnlyList<string> Methods { get; }
string GetRequestBodyForContentType(string contentType, string method); string GetRequestBodyForContentType(ref string contentType, string method);
} }
} }

View File

@ -52,7 +52,7 @@ namespace Microsoft.HttpRepl
shell.ShellState.ConsoleManager.AddBreakHandler(() => source.Cancel()); shell.ShellState.ConsoleManager.AddBreakHandler(() => source.Cancel());
if (args.Length > 0) if (args.Length > 0)
{ {
if (string.Equals(args[0], "--help", StringComparison.OrdinalIgnoreCase)) if (string.Equals(args[0], "--help", StringComparison.OrdinalIgnoreCase) || string.Equals(args[0], "-h", StringComparison.OrdinalIgnoreCase))
{ {
shell.ShellState.ConsoleManager.WriteLine("Usage: dotnet httprepl [<BASE_ADDRESS>] [options]"); shell.ShellState.ConsoleManager.WriteLine("Usage: dotnet httprepl [<BASE_ADDRESS>] [options]");
shell.ShellState.ConsoleManager.WriteLine(); shell.ShellState.ConsoleManager.WriteLine();

View File

@ -79,7 +79,7 @@ namespace Microsoft.Repl.Commanding
public IParser Parser => _parser; public IParser Parser => _parser;
public IReadOnlyList<string> CollectSuggesetions(IShellState shellState) public IReadOnlyList<string> CollectSuggestions(IShellState shellState)
{ {
string line = shellState.InputManager.GetCurrentBuffer(); string line = shellState.InputManager.GetCurrentBuffer();
TParseResult parseResult = _parser.Parse(line, shellState.ConsoleManager.CaretPosition); TParseResult parseResult = _parser.Parse(line, shellState.ConsoleManager.CaretPosition);

View File

@ -12,7 +12,7 @@ namespace Microsoft.Repl.Commanding
{ {
IParser Parser { get; } IParser Parser { get; }
IReadOnlyList<string> CollectSuggesetions(IShellState shellState); IReadOnlyList<string> CollectSuggestions(IShellState shellState);
void OnReady(IShellState shellState); void OnReady(IShellState shellState);

View File

@ -50,37 +50,41 @@ namespace Microsoft.Repl.ConsoleHandling
return; return;
} }
int bufferWidth = Console.BufferWidth;
int cursorTop = Console.CursorTop;
int cursorLeft = Console.CursorLeft;
while (positions < 0 && CaretPosition > 0) while (positions < 0 && CaretPosition > 0)
{ {
if (-positions > Console.BufferWidth) if (-positions > bufferWidth)
{ {
if (Console.CursorTop == 0) if (cursorTop == 0)
{ {
Console.CursorLeft = 0; cursorLeft = 0;
positions = 0; positions = 0;
} }
else else
{ {
positions += Console.BufferWidth; positions += bufferWidth;
--Console.CursorTop; --cursorTop;
} }
} }
else else
{ {
int remaining = Console.CursorLeft + positions; int remaining = cursorLeft + positions;
if (remaining >= 0) if (remaining >= 0)
{ {
Console.CursorLeft = remaining; cursorLeft = remaining;
} }
else if (Console.CursorTop == 0) else if (cursorTop == 0)
{ {
Console.CursorLeft = 0; cursorLeft = 0;
} }
else else
{ {
--Console.CursorTop; --cursorTop;
Console.CursorLeft = Console.BufferWidth + remaining; cursorLeft = bufferWidth + remaining;
} }
positions = 0; positions = 0;
@ -89,27 +93,29 @@ namespace Microsoft.Repl.ConsoleHandling
while (positions > 0) while (positions > 0)
{ {
if (positions > Console.BufferWidth) if (positions > bufferWidth)
{ {
positions -= Console.BufferWidth; positions -= bufferWidth;
++Console.CursorTop; ++cursorTop;
} }
else else
{ {
int spaceLeftOnLine = Console.BufferWidth - Console.CursorLeft - 1; int spaceLeftOnLine = bufferWidth - cursorLeft - 1;
if (positions > spaceLeftOnLine) if (positions > spaceLeftOnLine)
{ {
++Console.CursorTop; ++cursorTop;
Console.CursorLeft = positions - spaceLeftOnLine - 1; cursorLeft = positions - spaceLeftOnLine - 1;
} }
else else
{ {
Console.CursorLeft += positions; cursorLeft += positions;
} }
positions = 0; positions = 0;
} }
} }
Console.SetCursorPosition(cursorLeft, cursorTop);
} }
} }

View File

@ -112,14 +112,22 @@ namespace Microsoft.Repl.Input
private void StashEchoState() private void StashEchoState()
{ {
_ttyState = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX) string sttyFlags = null;
? GetTtyState() if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX))
: null;
if (!string.IsNullOrEmpty(_ttyState))
{ {
//"gfmt1:cflag=4300:iflag=6b02:lflag=200005c7:oflag=3:discard=f:dsusp=19:eof=4:eol=ff:eol2=ff:erase=7f:intr=3:kill=15:lnext=16:min=1:quit=1c:reprint=12:start=11:status=14:stop=13:susp=1a:time=0:werase=17:ispeed=38400:ospeed=38400\n" _ttyState = GetTtyState();
ProcessStartInfo psi = new ProcessStartInfo("stty", "gfmt1:erase=08:werase=08 -echo"); sttyFlags = "gfmt1:erase=08:werase=08 -echo";
}
//If it's any of the ubuntu variants on 18.x, stty tweaks are required
else if (System.Runtime.InteropServices.RuntimeInformation.OSDescription.IndexOf("buntu", StringComparison.OrdinalIgnoreCase) > -1)
{
_ttyState = GetTtyState();
sttyFlags = "erase 0x08 werase 0x08 -echo";
}
if (!string.IsNullOrEmpty(sttyFlags))
{
ProcessStartInfo psi = new ProcessStartInfo("stty", sttyFlags);
Process p = Process.Start(psi); Process p = Process.Start(psi);
p?.WaitForExit(); p?.WaitForExit();
} }
@ -133,7 +141,7 @@ namespace Microsoft.Repl.Input
}; };
Process p = Process.Start(psi); Process p = Process.Start(psi);
p?.WaitForExit(); p?.WaitForExit();
string result = p?.StandardOutput.ReadToEnd(); string result = p?.StandardOutput.ReadToEnd().Trim();
return result; return result;
} }
@ -331,7 +339,7 @@ namespace Microsoft.Repl.Input
} }
private void FlushInput(IShellState state, ref List<ConsoleKeyInfo> presses) private void FlushInput(IShellState state, ref List<ConsoleKeyInfo> presses)
{ {
string str = new string(presses.Select(x => x.KeyChar).ToArray()); string str = new string(presses.Select(x => x.KeyChar).ToArray());
if (state.ConsoleManager.CaretPosition == _inputBuffer.Count) if (state.ConsoleManager.CaretPosition == _inputBuffer.Count)

View File

@ -36,7 +36,7 @@ namespace Microsoft.Repl.Suggestions
else else
{ {
_currentSuggestion = 0; _currentSuggestion = 0;
_suggestions = shellState.CommandDispatcher.CollectSuggesetions(shellState); _suggestions = shellState.CommandDispatcher.CollectSuggestions(shellState);
if (_suggestions == null || _suggestions.Count == 0) if (_suggestions == null || _suggestions.Count == 0)
{ {
@ -76,7 +76,7 @@ namespace Microsoft.Repl.Suggestions
} }
else else
{ {
_suggestions = shellState.CommandDispatcher.CollectSuggesetions(shellState); _suggestions = shellState.CommandDispatcher.CollectSuggestions(shellState);
_currentSuggestion = _suggestions.Count - 1; _currentSuggestion = _suggestions.Count - 1;
if (_suggestions == null || _suggestions.Count == 0) if (_suggestions == null || _suggestions.Count == 0)