From 377f68b1932fc24607a2f9f4d1ec0907fa2522e4 Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Fri, 10 Apr 2020 16:40:30 -0400 Subject: [PATCH 1/6] Support json as config --- .../ConfigModel/ConfigFactory.cs | 19 +++++++++++++++ .../Serialization/YamlSerializer.cs | 15 ++++++++++++ src/tye/InitHost.cs | 23 ++++++++++++++----- src/tye/Program.InitCommand.cs | 10 ++++++-- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.Tye.Core/ConfigModel/ConfigFactory.cs b/src/Microsoft.Tye.Core/ConfigModel/ConfigFactory.cs index e6f5a3f44..31097eb27 100644 --- a/src/Microsoft.Tye.Core/ConfigModel/ConfigFactory.cs +++ b/src/Microsoft.Tye.Core/ConfigModel/ConfigFactory.cs @@ -3,8 +3,13 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Dynamic; using System.IO; +using k8s; +using k8s.Models; using Microsoft.Tye.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using Tye.Serialization; namespace Microsoft.Tye.ConfigModel @@ -16,6 +21,9 @@ public static ConfigApplication FromFile(FileInfo file) var extension = file.Extension.ToLowerInvariant(); switch (extension) { + case ".json": + return FromJson(file); + case ".yaml": case ".yml": return FromYaml(file); @@ -88,5 +96,16 @@ private static ConfigApplication FromYaml(FileInfo file) using var parser = new YamlParser(file); return parser.ParseConfigApplication(); } + + private static ConfigApplication FromJson(FileInfo file) + { + var converter = new ExpandoObjectConverter(); + dynamic obj = JsonConvert.DeserializeObject(file.OpenText().ReadToEnd(), converter); + var serializer = new YamlDotNet.Serialization.Serializer(); + string yamlContent = serializer.Serialize(obj); + + using var parser = new YamlParser(yamlContent); + return parser.ParseConfigApplication(); + } } } diff --git a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs index 4fc55be52..a334575df 100644 --- a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs +++ b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using k8s; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; @@ -17,5 +18,19 @@ public static ISerializer CreateSerializer() .WithEmissionPhaseObjectGraphVisitor(args => new OmitDefaultAndEmptyArrayObjectGraphVisitor(args.InnerVisitor)) .Build(); } + + public static string ConvertToJson(string yamlContent) + { + var deserializer = new DeserializerBuilder().Build(); + var yamlObject = deserializer.Deserialize(yamlContent); + + var serializer = new SerializerBuilder() + .JsonCompatible() + .Build(); + + var json = serializer.Serialize(yamlObject); + + return json; + } } } diff --git a/src/tye/InitHost.cs b/src/tye/InitHost.cs index 435042369..eb17ab556 100644 --- a/src/tye/InitHost.cs +++ b/src/tye/InitHost.cs @@ -6,21 +6,32 @@ namespace Microsoft.Tye { public static class InitHost { - public static string CreateTyeFile(FileInfo? path, bool force) + public static string CreateTyeFile(FileInfo? path, bool force, bool json = false) { - var (content, outputFilePath) = CreateTyeFileContent(path, force); + var (content, outputFilePath) = CreateTyeFileContent(path, force, json); - File.WriteAllText(outputFilePath, content); + if (json) + { + var jsonContent = YamlSerializer.ConvertToJson(content); + File.WriteAllText(outputFilePath, jsonContent); + } + else + { + File.WriteAllText(outputFilePath, content); + } return outputFilePath; } - public static (string, string) CreateTyeFileContent(FileInfo? path, bool force) + public static (string, string) CreateTyeFileContent(FileInfo? path, bool force, bool json = false) { if (path is FileInfo && path.Exists && !force) { ThrowIfTyeFilePresent(path, "tye.yml"); ThrowIfTyeFilePresent(path, "tye.yaml"); + + if (json) + ThrowIfTyeFilePresent(path, "tye.json"); } var template = @" @@ -50,7 +61,7 @@ public static (string, string) CreateTyeFileContent(FileInfo? path, bool force) // Output in the current directory unless an input file was provided, then // output next to the input file. - var outputFilePath = "tye.yaml"; + var outputFilePath = json ? "tye.json" : "tye.yaml"; if (path is FileInfo && path.Exists) { @@ -77,7 +88,7 @@ public static (string, string) CreateTyeFileContent(FileInfo? path, bool force) } // If the input file is a sln/project then place the config next to it - outputFilePath = Path.Combine(directory.FullName, "tye.yaml"); + outputFilePath = Path.Combine(directory.FullName, outputFilePath); } else { diff --git a/src/tye/Program.InitCommand.cs b/src/tye/Program.InitCommand.cs index aa6f117fa..bf2381c9b 100644 --- a/src/tye/Program.InitCommand.cs +++ b/src/tye/Program.InitCommand.cs @@ -21,15 +21,21 @@ private static Command CreateInitCommand() CommonArguments.Path_Optional, }; + command.AddOption(new Option(new[] { "--json" }) + { + Description = "Create config file in json format i.e. tye.json", + Required = false + }); + command.AddOption(new Option(new[] { "-f", "--force" }) { Description = "Overrides the tye.yaml file if already present for project.", Required = false }); - command.Handler = CommandHandler.Create((console, path, force) => + command.Handler = CommandHandler.Create((console, path, force, json) => { - var outputFilePath = InitHost.CreateTyeFile(path, force); + var outputFilePath = InitHost.CreateTyeFile(path, force, json); console.Out.WriteLine($"Created '{outputFilePath}'."); }); From 7464c28e6b5edf2e3c950b5f3335daef8e511129 Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Fri, 10 Apr 2020 16:43:56 -0400 Subject: [PATCH 2/6] fix formatting --- src/tye/InitHost.cs | 2 +- tye.sln | 33 ++++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/tye/InitHost.cs b/src/tye/InitHost.cs index eb17ab556..f9f3215dc 100644 --- a/src/tye/InitHost.cs +++ b/src/tye/InitHost.cs @@ -61,7 +61,7 @@ public static (string, string) CreateTyeFileContent(FileInfo? path, bool force, // Output in the current directory unless an input file was provided, then // output next to the input file. - var outputFilePath = json ? "tye.json" : "tye.yaml"; + var outputFilePath = json ? "tye.json" : "tye.yaml"; if (path is FileInfo && path.Exists) { diff --git a/tye.sln b/tye.sln index c52c1d60d..2576ba7c0 100644 --- a/tye.sln +++ b/tye.sln @@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 16.0.29613.14 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8C662D59-A3CB-466F-8E85-A8E6BA5E7601}" + ProjectSection(SolutionItems) = preProject + src\tye\InitHost.cs = src\tye\InitHost.cs + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tye", "src\tye\tye.csproj", "{9BFE4070-D6D8-41F8-B92E-F85C3DCD7AB8}" EndProject @@ -25,9 +28,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Tye.Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Tye.Extensions.Configuration", "src\Microsoft.Tye.Extensions.Configuration\Microsoft.Tye.Extensions.Configuration.csproj", "{B07394E4-30A7-429A-BC5A-747B54D5A447}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Tye.Proxy", "src\Microsoft.Tye.Proxy\Microsoft.Tye.Proxy.csproj", "{7C9021B7-64BA-4DA9-88DA-5BC12A1C6233}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Tye.Proxy", "src\Microsoft.Tye.Proxy\Microsoft.Tye.Proxy.csproj", "{7C9021B7-64BA-4DA9-88DA-5BC12A1C6233}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Tye.Extensions.Configuration.Tests", "test\Microsoft.Tye.Extensions.Configuration.Tests\Microsoft.Tye.Extensions.Configuration.Tests.csproj", "{FCE7C889-16D1-42E7-A514-EA096E9D41A7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Tye.Extensions.Configuration.Tests", "test\Microsoft.Tye.Extensions.Configuration.Tests\Microsoft.Tye.Extensions.Configuration.Tests.csproj", "{FCE7C889-16D1-42E7-A514-EA096E9D41A7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -111,6 +114,18 @@ Global {D0359C69-6EA9-4B03-9455-90E8E04F1CB0}.Release|x64.Build.0 = Release|Any CPU {D0359C69-6EA9-4B03-9455-90E8E04F1CB0}.Release|x86.ActiveCfg = Release|Any CPU {D0359C69-6EA9-4B03-9455-90E8E04F1CB0}.Release|x86.Build.0 = Release|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x64.ActiveCfg = Debug|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x64.Build.0 = Debug|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x86.ActiveCfg = Debug|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x86.Build.0 = Debug|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|Any CPU.Build.0 = Release|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x64.ActiveCfg = Release|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x64.Build.0 = Release|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x86.ActiveCfg = Release|Any CPU + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x86.Build.0 = Release|Any CPU {AAF0CE0B-E53A-4E10-AA82-BF7200AB2B0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AAF0CE0B-E53A-4E10-AA82-BF7200AB2B0C}.Debug|Any CPU.Build.0 = Debug|Any CPU {AAF0CE0B-E53A-4E10-AA82-BF7200AB2B0C}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -147,18 +162,6 @@ Global {7C9021B7-64BA-4DA9-88DA-5BC12A1C6233}.Release|x64.Build.0 = Release|Any CPU {7C9021B7-64BA-4DA9-88DA-5BC12A1C6233}.Release|x86.ActiveCfg = Release|Any CPU {7C9021B7-64BA-4DA9-88DA-5BC12A1C6233}.Release|x86.Build.0 = Release|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x64.ActiveCfg = Debug|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x64.Build.0 = Debug|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x86.ActiveCfg = Debug|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Debug|x86.Build.0 = Debug|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|Any CPU.Build.0 = Release|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x64.ActiveCfg = Release|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x64.Build.0 = Release|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x86.ActiveCfg = Release|Any CPU - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A}.Release|x86.Build.0 = Release|Any CPU {FCE7C889-16D1-42E7-A514-EA096E9D41A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FCE7C889-16D1-42E7-A514-EA096E9D41A7}.Debug|Any CPU.Build.0 = Debug|Any CPU {FCE7C889-16D1-42E7-A514-EA096E9D41A7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -182,10 +185,10 @@ Global {CEBFC149-8162-4A0A-9AD4-40498B9172CD} = {8C662D59-A3CB-466F-8E85-A8E6BA5E7601} {34719884-1338-4965-BA2A-F98DB03733C2} = {8C662D59-A3CB-466F-8E85-A8E6BA5E7601} {D0359C69-6EA9-4B03-9455-90E8E04F1CB0} = {8C662D59-A3CB-466F-8E85-A8E6BA5E7601} + {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A} = {F19B02EB-A372-417A-B2C2-EA0D5A3C76D5} {AAF0CE0B-E53A-4E10-AA82-BF7200AB2B0C} = {8C662D59-A3CB-466F-8E85-A8E6BA5E7601} {B07394E4-30A7-429A-BC5A-747B54D5A447} = {8C662D59-A3CB-466F-8E85-A8E6BA5E7601} {7C9021B7-64BA-4DA9-88DA-5BC12A1C6233} = {8C662D59-A3CB-466F-8E85-A8E6BA5E7601} - {2233F4A8-10F9-40A6-BFD3-8D0C37F8359A} = {F19B02EB-A372-417A-B2C2-EA0D5A3C76D5} {FCE7C889-16D1-42E7-A514-EA096E9D41A7} = {F19B02EB-A372-417A-B2C2-EA0D5A3C76D5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution From 723a0e10a2e78de51ce2a987ae42add29eacba09 Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Fri, 10 Apr 2020 16:52:35 -0400 Subject: [PATCH 3/6] git extension doing funky things... --- tye.sln | 3 --- 1 file changed, 3 deletions(-) diff --git a/tye.sln b/tye.sln index 2576ba7c0..2366f41e5 100644 --- a/tye.sln +++ b/tye.sln @@ -4,9 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 16.0.29613.14 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8C662D59-A3CB-466F-8E85-A8E6BA5E7601}" - ProjectSection(SolutionItems) = preProject - src\tye\InitHost.cs = src\tye\InitHost.cs - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tye", "src\tye\tye.csproj", "{9BFE4070-D6D8-41F8-B92E-F85C3DCD7AB8}" EndProject From 2f53df654b67bba6b2956188e30c08cf4734206f Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Mon, 13 Apr 2020 11:39:31 -0400 Subject: [PATCH 4/6] addressing feedback --- src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs | 6 +++++- src/tye/InitHost.cs | 4 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs index a334575df..db298ad02 100644 --- a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs +++ b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using k8s; +using System.Linq; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; @@ -21,6 +21,7 @@ public static ISerializer CreateSerializer() public static string ConvertToJson(string yamlContent) { + var schema = "\"$schema\" : \"https://raw.githubusercontent.com/dotnet/tye/master/src/schema/tye-schema.json\","; var deserializer = new DeserializerBuilder().Build(); var yamlObject = deserializer.Deserialize(yamlContent); @@ -29,6 +30,9 @@ public static string ConvertToJson(string yamlContent) .Build(); var json = serializer.Serialize(yamlObject); + + if (string.IsNullOrEmpty(json)) + json = json.Insert(json.IndexOf("{"), schema); return json; } diff --git a/src/tye/InitHost.cs b/src/tye/InitHost.cs index f9f3215dc..9c27bcf60 100644 --- a/src/tye/InitHost.cs +++ b/src/tye/InitHost.cs @@ -29,9 +29,7 @@ public static (string, string) CreateTyeFileContent(FileInfo? path, bool force, { ThrowIfTyeFilePresent(path, "tye.yml"); ThrowIfTyeFilePresent(path, "tye.yaml"); - - if (json) - ThrowIfTyeFilePresent(path, "tye.json"); + ThrowIfTyeFilePresent(path, "tye.json"); } var template = @" From cf8b4230098e7d5e0bd389f0e156e68c32945a3e Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Mon, 13 Apr 2020 11:45:46 -0400 Subject: [PATCH 5/6] +1 insert of schema location --- src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs index db298ad02..7da852138 100644 --- a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs +++ b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs @@ -32,7 +32,7 @@ public static string ConvertToJson(string yamlContent) var json = serializer.Serialize(yamlObject); if (string.IsNullOrEmpty(json)) - json = json.Insert(json.IndexOf("{"), schema); + json = json.Insert(json.IndexOf("{") + 1, schema); return json; } From 03b992415619204c6b808882654ca73b00f0e401 Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Mon, 13 Apr 2020 11:48:14 -0400 Subject: [PATCH 6/6] format caught me again. --- src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs index 7da852138..205972862 100644 --- a/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs +++ b/src/Microsoft.Tye.Core/Serialization/YamlSerializer.cs @@ -30,7 +30,7 @@ public static string ConvertToJson(string yamlContent) .Build(); var json = serializer.Serialize(yamlObject); - + if (string.IsNullOrEmpty(json)) json = json.Insert(json.IndexOf("{") + 1, schema);