diff --git a/AutoRest/AutoRest.Core.Tests/AutoRest.Core.Tests.csproj b/AutoRest/AutoRest.Core.Tests/AutoRest.Core.Tests.csproj
index cabe0eda3b4ee..e19fdb0d8c5af 100644
--- a/AutoRest/AutoRest.Core.Tests/AutoRest.Core.Tests.csproj
+++ b/AutoRest/AutoRest.Core.Tests/AutoRest.Core.Tests.csproj
@@ -88,6 +88,9 @@
PreserveNewest
+
+ Always
+
diff --git a/AutoRest/AutoRest.Core.Tests/AutoRestSettingsTests.cs b/AutoRest/AutoRest.Core.Tests/AutoRestSettingsTests.cs
index 0b8d7dc34a871..f11f448205c3b 100644
--- a/AutoRest/AutoRest.Core.Tests/AutoRestSettingsTests.cs
+++ b/AutoRest/AutoRest.Core.Tests/AutoRestSettingsTests.cs
@@ -1,9 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
+using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
+using System.Reflection;
using Microsoft.Rest.Generator.Logging;
+using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.Rest.Generator.Test
@@ -16,11 +20,11 @@ public void CreateWithoutArgumentsReturnsBlankSettings()
{
var settings = Settings.Create((string[]) null);
Assert.NotNull(settings);
- settings = Settings.Create((IDictionary) null);
+ settings = Settings.Create((IDictionary) null);
Assert.NotNull(settings);
settings = Settings.Create(new string[0]);
Assert.NotNull(settings);
- settings = Settings.Create(new Dictionary());
+ settings = Settings.Create(new Dictionary());
Assert.NotNull(settings);
}
@@ -33,6 +37,23 @@ public void CreateWithMultipleEmptyKeysStoreInCustomDictonary()
Assert.Equal("", settings.CustomSettings["Bar"]);
}
+ [Fact]
+ public void LoadCodeGenSettingsFromJsonFile()
+ {
+ var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase);
+ var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
+ var dirPath = Path.GetDirectoryName(codeBasePath);
+ var settingsFile = Path.Combine(dirPath, "Resource\\SampleSettings.json");
+ var settings = Settings.Create(new[] {"-cgs", settingsFile});
+ Assert.False((bool) settings.CustomSettings["sampleSwitchFalse"]);
+ Assert.True((bool) settings.CustomSettings["sampleSwitchTrue"]);
+ Assert.Equal("Foo", settings.CustomSettings["sampleString"]);
+ Assert.Equal(typeof (JArray), settings.CustomSettings["filePathArray"].GetType());
+ Assert.Equal(2, ((JArray) settings.CustomSettings["filePathArray"]).Count);
+ Assert.Equal(typeof (JArray), settings.CustomSettings["intArray"].GetType());
+ Assert.Equal(typeof (long), settings.CustomSettings["intFoo"].GetType());
+ }
+
[Fact]
public void EmptyCredentialsSettingIsSetToTrueIfPassed()
{
diff --git a/AutoRest/AutoRest.Core.Tests/Resource/SampleSettings.json b/AutoRest/AutoRest.Core.Tests/Resource/SampleSettings.json
new file mode 100644
index 0000000000000..6ee036cba2536
--- /dev/null
+++ b/AutoRest/AutoRest.Core.Tests/Resource/SampleSettings.json
@@ -0,0 +1,8 @@
+{
+ "sampleSwitchFalse": false,
+ "sampleSwitchTrue": true,
+ "sampleString": "Foo",
+ "filePathArray": [ "C:\\Foo.dll", "C:\\Bar.dll" ],
+ "intArray": [ 1, 2, 3 ],
+ "intFoo": 5
+}
diff --git a/AutoRest/AutoRest.Core/CodeGenerator.cs b/AutoRest/AutoRest.Core/CodeGenerator.cs
index 57dbecb697346..55e20dee7c539 100644
--- a/AutoRest/AutoRest.Core/CodeGenerator.cs
+++ b/AutoRest/AutoRest.Core/CodeGenerator.cs
@@ -56,7 +56,7 @@ public virtual string HeaderFileExtension
/// Populate settings on self and any child objects
///
/// A dictionary of settings
- public virtual void PopulateSettings(IDictionary settings)
+ public virtual void PopulateSettings(IDictionary settings)
{
Settings.PopulateSettings(this, settings);
}
diff --git a/AutoRest/AutoRest.Core/Properties/Resources.Designer.cs b/AutoRest/AutoRest.Core/Properties/Resources.Designer.cs
index 2ef7dbdc586ae..975a7983ee085 100644
--- a/AutoRest/AutoRest.Core/Properties/Resources.Designer.cs
+++ b/AutoRest/AutoRest.Core/Properties/Resources.Designer.cs
@@ -78,6 +78,15 @@ internal static string CodeGenerationFailed {
}
}
+ ///
+ /// Looks up a localized string similar to Could not load CodeGenSettings file '{0}'. Exception: '{1}'..
+ ///
+ internal static string CodeGenSettingsFileInvalid {
+ get {
+ return ResourceManager.GetString("CodeGenSettingsFileInvalid", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to \\\\.
///
diff --git a/AutoRest/AutoRest.Core/Properties/Resources.resx b/AutoRest/AutoRest.Core/Properties/Resources.resx
index 18688acae3326..17f3fe59fa18b 100644
--- a/AutoRest/AutoRest.Core/Properties/Resources.resx
+++ b/AutoRest/AutoRest.Core/Properties/Resources.resx
@@ -123,6 +123,9 @@
Code generation failed with errors. See inner exceptions for details.
+
+ Could not load CodeGenSettings file '{0}'. Exception: '{1}'.
+
\\\\
diff --git a/AutoRest/AutoRest.Core/Settings.cs b/AutoRest/AutoRest.Core/Settings.cs
index 63675cf0e46b4..81ea5ca05c3df 100644
--- a/AutoRest/AutoRest.Core/Settings.cs
+++ b/AutoRest/AutoRest.Core/Settings.cs
@@ -10,6 +10,8 @@
using Microsoft.Rest.Generator.Properties;
using Microsoft.Rest.Generator.Utilities;
using System.Globalization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
namespace Microsoft.Rest.Generator
{
@@ -46,7 +48,7 @@ public Settings()
{
FileSystem = new FileSystem();
OutputDirectory = Path.Combine(Environment.CurrentDirectory, "Generated");
- CustomSettings = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ CustomSettings = new Dictionary(StringComparer.OrdinalIgnoreCase);
Header = string.Format(CultureInfo.InvariantCulture, DefaultCodeGenerationHeader, AutoRest.Version);
CodeGenerator = "CSharp";
Modeler = "Swagger";
@@ -60,7 +62,7 @@ public Settings()
///
/// Custom provider specific settings.
///
- public IDictionary CustomSettings { get; private set; }
+ public IDictionary CustomSettings { get; private set; }
// The CommandLineInfo attribute is reflected to display help.
// Prefer to show required properties before optional.
@@ -215,6 +217,9 @@ public string Header
[SettingsInfo("Package version of then generated code package. Should be then version wanted for the package in then package manager.")]
public string PackageVersion { get; set; }
+ [SettingsAlias("cgs")]
+ [SettingsInfo("The path for a json file containing code generation settings.")]
+ public string CodeGenSettings { get; set; }
///
/// Factory method to generate CodeGenerationSettings from command line arguments.
/// Matches dictionary keys to the settings properties.
@@ -223,7 +228,7 @@ public string Header
/// CodeGenerationSettings
public static Settings Create(string[] arguments)
{
- var argsDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ var argsDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
if (arguments != null && arguments.Length > 0)
{
string key = null;
@@ -257,7 +262,7 @@ public static Settings Create(string[] arguments)
return Create(argsDictionary);
}
- private static void AddArgumentToDictionary(string key, string value, Dictionary argsDictionary)
+ private static void AddArgumentToDictionary(string key, string value, IDictionary argsDictionary)
{
key = key ?? "Default";
value = value ?? String.Empty;
@@ -270,7 +275,7 @@ private static void AddArgumentToDictionary(string key, string value, Dictionary
///
/// Dictionary of settings
/// Settings
- public static Settings Create(IDictionary settings)
+ public static Settings Create(IDictionary settings)
{
var autoRestSettings = new Settings();
if (settings == null || settings.Count == 0)
@@ -281,6 +286,16 @@ public static Settings Create(IDictionary settings)
PopulateSettings(autoRestSettings, settings);
autoRestSettings.CustomSettings = settings;
+ if (!string.IsNullOrEmpty(autoRestSettings.CodeGenSettings))
+ {
+ var settingsContent = autoRestSettings.FileSystem.ReadFileAsText(autoRestSettings.CodeGenSettings);
+ var codeGenSettingsDictionary =
+ JsonConvert.DeserializeObject>(settingsContent);
+ foreach (var pair in codeGenSettingsDictionary)
+ {
+ autoRestSettings.CustomSettings[pair.Key] = pair.Value;
+ }
+ }
return autoRestSettings;
}
@@ -290,7 +305,7 @@ public static Settings Create(IDictionary settings)
/// Object to populate from dictionary.
/// Dictionary of settings.Settings that are populated get removed from the dictionary.
/// Dictionary of settings that were not matched.
- public static void PopulateSettings(object entityToPopulate, IDictionary settings)
+ public static void PopulateSettings(object entityToPopulate, IDictionary settings)
{
if (entityToPopulate == null)
{
@@ -311,13 +326,33 @@ public static void PopulateSettings(object entityToPopulate, IDictionary c.ToString())
+ .ToArray();
+
+ property.SetValue(entityToPopulate, stringArray);
+ }
+ else if (elementType == typeof (int))
+ {
+ var intValues = ((JArray)setting.Value).Children().
+ Select(c => (int)Convert.ChangeType(c, elementType, CultureInfo.InvariantCulture))
+ .ToArray();
+ property.SetValue(entityToPopulate, intValues);
+ }
}
else
{
diff --git a/AutoRest/Generators/CSharp/Azure.CSharp/AzureCSharpCodeNamer.cs b/AutoRest/Generators/CSharp/Azure.CSharp/AzureCSharpCodeNamer.cs
index 2fb396c256361..2b5f005ed0323 100644
--- a/AutoRest/Generators/CSharp/Azure.CSharp/AzureCSharpCodeNamer.cs
+++ b/AutoRest/Generators/CSharp/Azure.CSharp/AzureCSharpCodeNamer.cs
@@ -33,7 +33,7 @@ public AzureCSharpCodeNamer(Settings settings)
if (setting.Equals("useDateTimeOffset", StringComparison.OrdinalIgnoreCase))
{
bool toUse;
- if (bool.TryParse(settings.CustomSettings[setting], out toUse))
+ if (bool.TryParse(settings.CustomSettings[setting].ToString(), out toUse))
{
UseDateTimeOffset = toUse;
}
diff --git a/AutoRest/Generators/CSharp/CSharp/CSharpCodeGenerator.cs b/AutoRest/Generators/CSharp/CSharp/CSharpCodeGenerator.cs
index 5b3ba7981eb0c..8834f4c010834 100644
--- a/AutoRest/Generators/CSharp/CSharp/CSharpCodeGenerator.cs
+++ b/AutoRest/Generators/CSharp/CSharp/CSharpCodeGenerator.cs
@@ -60,7 +60,7 @@ public override string ImplementationFileExtension
get { return ".cs"; }
}
- public override void PopulateSettings(IDictionary settings)
+ public override void PopulateSettings(IDictionary settings)
{
base.PopulateSettings(settings);
Settings.PopulateSettings(_namer, settings);
diff --git a/AutoRest/Generators/Ruby/Ruby/RubyCodeGenerator.cs b/AutoRest/Generators/Ruby/Ruby/RubyCodeGenerator.cs
index 368888b082657..114540a6c5372 100644
--- a/AutoRest/Generators/Ruby/Ruby/RubyCodeGenerator.cs
+++ b/AutoRest/Generators/Ruby/Ruby/RubyCodeGenerator.cs
@@ -58,7 +58,7 @@ public RubyCodeGenerator(Settings settings) : base(settings)
if (Settings.CustomSettings.ContainsKey("Name"))
{
- this.sdkName = Settings.CustomSettings["Name"];
+ this.sdkName = Settings.CustomSettings["Name"].ToString();
}
if (sdkName == null)
diff --git a/AutoRest/Modelers/Swagger/SwaggerModeler.cs b/AutoRest/Modelers/Swagger/SwaggerModeler.cs
index 9a009c4a77d99..829fbc174cad2 100644
--- a/AutoRest/Modelers/Swagger/SwaggerModeler.cs
+++ b/AutoRest/Modelers/Swagger/SwaggerModeler.cs
@@ -144,7 +144,9 @@ private void UpdateSettings()
{
foreach (var key in ServiceDefinition.Info.CodeGenerationSettings.Extensions.Keys)
{
- this.Settings.CustomSettings[key] = ServiceDefinition.Info.CodeGenerationSettings.Extensions[key].ToString();
+ //Don't overwrite settings that come in from the command line
+ if (!this.Settings.CustomSettings.ContainsKey(key))
+ this.Settings.CustomSettings[key] = ServiceDefinition.Info.CodeGenerationSettings.Extensions[key];
}
Settings.PopulateSettings(this.Settings, this.Settings.CustomSettings);
}
diff --git a/Documentation/cli.md b/Documentation/cli.md
index 4dddaeec8a919..ee9159e5f39d9 100644
--- a/Documentation/cli.md
+++ b/Documentation/cli.md
@@ -25,7 +25,8 @@
**-OutputFileName** If set, will cause generated code to be output to a single file. Not supported by all code generators.
**-Verbose** If set, will output verbose diagnostic messages.
-
+
+ **-CodeGenSettings** Optionally specifies a JSON file that contains code generation settings equivalent to the swagger document containing the same content in the [x-ms-code-generation-settings] extension. Aliases: -cgs
##Code Generators
**Ruby** Generic Ruby code generator.
@@ -68,7 +69,7 @@ AutoRest.exe -Namespace MyNamespace -Input swagger.json
AutoRest.exe -Namespace MyNamespace -Header "Copyright Contoso Ltd" -Input swagger.json
```
- - Generate C# client with a credentials property in MyNamespace from swagger.json input:
+ - Generate C# client with a credentials property in MyNamespace from swagger.json input and with code generation settings specified by settings.json:
```bash
-AutoRest.exe -AddCredentials true -Namespace MyNamespace -CodeGenerator CSharp -Modeler Swagger -Input swagger.json
+AutoRest.exe -AddCredentials true -Namespace MyNamespace -CodeGenerator CSharp -Modeler Swagger -Input swagger.json -CodeGenSettings settings.json
```
diff --git a/Documentation/swagger-extensions.md b/Documentation/swagger-extensions.md
index 1fbf0efe46d71..af5ab33f28f9b 100644
--- a/Documentation/swagger-extensions.md
+++ b/Documentation/swagger-extensions.md
@@ -39,7 +39,8 @@ Field Name | Type | Description
"info": {
"x-ms-code-generation-settings": {
"header": "MIT",
- "internalConstructors": true
+ "internalConstructors": true,
+ "useDateTimeOffset": true
}
}
```