Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core/AutoRest.Core/Parsing/YamlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static string Serialize(this YamlNode node)
{
using (var writer = new StringWriter())
{
new YamlStream(new YamlDocument(node)).Save(writer);
new YamlStream(new YamlDocument(node)).Save(writer, false);
return writer.ToString();
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/AutoRest.Core/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ public string Header
[SettingsInfo("The input validation severity level that will prevent code generation")]
public Category ValidationLevel { get; set; }

/// <summary>
/// If set, preprocesses a swagger file by expanding and resolving some advanced convenience syntax.
/// </summary>
[SettingsAlias("preprocessor")]
public bool Preprocessor { get; set; }

/// <summary>
/// Factory method to generate CodeGenerationSettings from command line arguments.
/// Matches dictionary keys to the settings properties.
Expand Down
70 changes: 70 additions & 0 deletions src/core/AutoRest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
using AutoRest.Simplify;
using static AutoRest.Core.Utilities.DependencyInjection;
using System.IO;
using AutoRest.Core.Parsing;
using YamlDotNet.RepresentationModel;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace AutoRest
{
Expand All @@ -37,6 +41,13 @@ private static int Main(string[] args)
settings.Verbose));
Logger.Instance.AddListener(new SignalingLogListener(Category.Error, _ => generationFailed = true));

// internal preprocesor
if (settings.Preprocessor)
{
Console.Write(InternalPreprocessor(settings.FileSystem.ReadFileAsText(settings.Input)));
return 0;
}

// determine some reasonable default namespace
if (settings.Namespace == null)
{
Expand Down Expand Up @@ -129,5 +140,64 @@ private static bool IsShowMarkdownHelpIncluded(string[] args)
}
return false;
}

private static string InternalPreprocessor(string preSwagger)
{
var yaml = preSwagger.ParseYaml() as YamlMappingNode;

Func<string, string> getHeaderNameFromRefPath = refPath =>
{
var match = Regex.Match(refPath, @"\#\/headers/(?<name>.*)");
return match.Success
? match.Groups["name"].Value
: null;
};

// resolve headers
var headersSection = yaml?.Get("headers") as YamlMappingNode;
if (headersSection != null)
{
var paths1 = (yaml.Get("paths") as YamlMappingNode)?.Select(x => x.Value) ?? new YamlNode[0];
var paths2 = (yaml.Get("x-paths") as YamlMappingNode)?.Select(x => x.Value) ?? new YamlNode[0];
var operations = paths1.Concat(paths2).OfType<YamlMappingNode>().SelectMany(x => x.Children).Select(x => x.Value).OfType<YamlMappingNode>();
var responses = operations.Select(x => x.Get("responses")).OfType<YamlMappingNode>();
var statusCodes = responses.SelectMany(x => x.Children).Select(x => x.Value).OfType<YamlMappingNode>();
foreach (var statusCode in statusCodes.ToList())
{
var headersNode = statusCode.Get("headers");
var headersNodeMapping = headersNode as YamlMappingNode;
var headersNodeSequence = headersNode as YamlSequenceNode;
if (headersNodeMapping != null)
{
foreach (var header in headersNodeMapping.Children.ToList())
{
var headerValue = header.Value as YamlMappingNode;
var refPath = (headerValue?.Get("$ref") as YamlScalarNode)?.Value;
if (refPath != null)
{
var refName = getHeaderNameFromRefPath(refPath);
headerValue = headerValue.MergeWith(headersSection.Get(refName) as YamlMappingNode);
headerValue.Remove("$ref");
}
headersNodeMapping.Children[header.Key] = headerValue;
}
}
if (headersNodeSequence != null)
{
var headersNodeNew = new YamlMappingNode();
foreach (var refPath in headersNodeSequence.Children.OfType<YamlMappingNode>().Select(x => x.Get("$ref")).OfType<YamlScalarNode>().Select(x => x.Value))
{
var refName = getHeaderNameFromRefPath(refPath);
headersNodeNew.Add(refName, headersSection.Get(refName));
}
statusCode.Set("headers", headersNodeNew);
}
}

yaml.Remove("headers");
}

return yaml.Serialize();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public override CodeModel Build()
// merge child swaggers
foreach (var childSwaggerPath in compositeSwaggerModel.Documents)
{
var childSwagger = Settings.FileSystem.ReadFileAsText(childSwaggerPath).ParseYaml() as YamlMappingNode;
var childSwaggerRaw = Settings.FileSystem.ReadFileAsText(childSwaggerPath);
childSwaggerRaw = SwaggerParser.Normalize(childSwaggerPath, childSwaggerRaw);
var childSwagger = childSwaggerRaw.ParseYaml() as YamlMappingNode;
if (childSwagger == null)
{
throw ErrorManager.CreateError("Failed parsing referenced Swagger file {0}.", childSwaggerPath);
Expand Down