diff --git a/YmlTransform.sln b/YmlTransform.sln index d3940df..530b267 100644 --- a/YmlTransform.sln +++ b/YmlTransform.sln @@ -1,10 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.13 +VisualStudioVersion = 15.0.27004.2002 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YmlTransform", "src\YmlTransform\YmlTransform.csproj", "{00EC6644-0EBF-44A8-8EDF-F73D06787377}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YmlTransform.Tests", "tests\YmlTransform.Tests\YmlTransform.Tests.csproj", "{BB5287AE-B720-4C65-80B0-15F4EB459BA4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,8 +17,15 @@ Global {00EC6644-0EBF-44A8-8EDF-F73D06787377}.Debug|Any CPU.Build.0 = Debug|Any CPU {00EC6644-0EBF-44A8-8EDF-F73D06787377}.Release|Any CPU.ActiveCfg = Release|Any CPU {00EC6644-0EBF-44A8-8EDF-F73D06787377}.Release|Any CPU.Build.0 = Release|Any CPU + {BB5287AE-B720-4C65-80B0-15F4EB459BA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB5287AE-B720-4C65-80B0-15F4EB459BA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB5287AE-B720-4C65-80B0-15F4EB459BA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB5287AE-B720-4C65-80B0-15F4EB459BA4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7C44AB57-BB9F-4E95-860F-1F96C74B11EB} + EndGlobalSection EndGlobal diff --git a/src/YmlTransform/Models/TransformItem.cs b/src/YmlTransform/Models/TransformItem.cs index 6bf5537..29aae94 100644 --- a/src/YmlTransform/Models/TransformItem.cs +++ b/src/YmlTransform/Models/TransformItem.cs @@ -4,34 +4,11 @@ namespace YmlTransform.Models { class TransformItem { - /// - /// Path of the item in the tree - /// public string Path { get; set; } - - /// - /// The type of the current item - /// public string Type { get; set; } - - /// - /// The languages of the item - /// public string Languages { get; set; } - - /// - /// The field id - /// public Guid FieldId { get; set; } - - /// - /// The value of the item - /// public string Value { get; set; } - - /// - /// Hint property aka human readable id - /// public string Hint { get; set; } } } \ No newline at end of file diff --git a/src/YmlTransform/Program.cs b/src/YmlTransform/Program.cs index 0e643eb..ee47c07 100644 --- a/src/YmlTransform/Program.cs +++ b/src/YmlTransform/Program.cs @@ -1,14 +1,8 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Rainbow.Model; -using Rainbow.Storage.Yaml; -using YmlTransform.Models; +using YmlTransform.Models; namespace YmlTransform { - static class Program + class Program { static void Main(string[] args) { @@ -16,62 +10,8 @@ static void Main(string[] args) var isValid = CommandLine.Parser.Default.ParseArgumentsStrict(args, options); if (isValid) { - var transformation = Newtonsoft.Json.JsonConvert.DeserializeObject>(File.ReadAllText(options.TransformFile)); - - Transform(options.Path, transformation, options.Recursive); - } - } - - private static void Transform(string path, List transformations, bool recursive) - { - var files = Directory.GetFiles(path, "*.yml", - recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); - - foreach (var file in files) - { - using (var fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) - { - var transformed = false; - var formatter = new YamlSerializationFormatter(null, null); - var item = new ProxyItem(formatter.ReadSerializedItem(fs, Path.GetFileName(file))); - - foreach (var t in transformations) - { - if (item.Path == t.Path) - { - if (t.Type == "Shared") - { - if (item.SharedFields.FirstOrDefault(a => a.FieldId == t.FieldId) is ProxyFieldValue field) - { - Console.WriteLine($"Updating file {file} section {t.Type} id {t.FieldId} to {t.Value}"); - field.Value = t.Value; - transformed = true; - } - } - else if (t.Type == "Languages") - { - if (item.Versions - .Where(a => t.Languages == "*") - .SelectMany(a => a.Fields) - .FirstOrDefault(a => a.FieldId == t.FieldId) is ProxyFieldValue field) - { - Console.WriteLine($"Updating file {file} section {t.Type} id {t.FieldId} to {t.Value}"); - field.Value = t.Value; - transformed = true; - } - } - } - } - - if (transformed) - { - Console.WriteLine($"Transformed: {file}"); - fs.SetLength(0); - formatter.WriteSerializedItem(item, fs); - } - } - + YmlTransformer.TransformPath(options.Path, options.TransformFile, options.Recursive); } } } -} \ No newline at end of file +} diff --git a/src/YmlTransform/YmlTransform.csproj b/src/YmlTransform/YmlTransform.csproj index fb5abc8..5d0caa4 100644 --- a/src/YmlTransform/YmlTransform.csproj +++ b/src/YmlTransform/YmlTransform.csproj @@ -81,6 +81,7 @@ + diff --git a/src/YmlTransform/YmlTransformer.cs b/src/YmlTransform/YmlTransformer.cs new file mode 100644 index 0000000..fa132f7 --- /dev/null +++ b/src/YmlTransform/YmlTransformer.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Rainbow.Model; +using Rainbow.Storage.Yaml; +using YmlTransform.Models; + +namespace YmlTransform +{ + public static class YmlTransformer + { + public static void TransformFile(string fileToTransform, string transformFile) + { + var transformation = GetTransformation(transformFile); + TransformSingle(transformation, fileToTransform); + } + + + public static void TransformPath(string path, string transformFile, bool recursive) + { + var transformations = GetTransformation(transformFile); + var files = Directory.GetFiles(path, "*.yml", + recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); + + foreach (var file in files) + { + TransformSingle(transformations, file); + } + } + + private static List GetTransformation(string transformFile) + { + var transformation = + Newtonsoft.Json.JsonConvert.DeserializeObject>(File.ReadAllText(transformFile)); + return transformation; + } + + private static void TransformSingle(List transformations, string file) + { + using (var fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) + { + var transformed = false; + var formatter = new YamlSerializationFormatter(null, null); + var item = new ProxyItem(formatter.ReadSerializedItem(fs, Path.GetFileName(file))); + + foreach (var transform in transformations) + { + if (item.Path == transform.Path) + { + if (transform.Type == "Shared") + { + if (item.SharedFields.FirstOrDefault(a => a.FieldId == transform.FieldId) is ProxyFieldValue field) + { + Console.WriteLine( + $"Updating file {file} section {transform.Type} id {transform.FieldId} to {transform.Value}"); + field.Value = transform.Value; + transformed = true; + } + } + else if (transform.Type == "Languages") + { + var fields = item.Versions + .Where(a => transform.Languages == "*") + .SelectMany(a => a.Fields) + .Where(a => a.FieldId == transform.FieldId); + + foreach (var itemFieldValue in fields) + { + var field = (ProxyFieldValue) itemFieldValue; + Console.WriteLine( + $"Updating file {file} section {transform.Type} id {transform.FieldId} to {transform.Value}"); + field.Value = transform.Value; + transformed = true; + } + } + } + } + + + if (transformed) + { + Console.WriteLine($"Transformed: {file}"); + fs.SetLength(0); + formatter.WriteSerializedItem(item, fs); + } + } + } + } +} diff --git a/tests/YmlTransform.Tests/Data/Multi-Language.yml b/tests/YmlTransform.Tests/Data/Multi-Language.yml new file mode 100644 index 0000000..4337bf5 --- /dev/null +++ b/tests/YmlTransform.Tests/Data/Multi-Language.yml @@ -0,0 +1,47 @@ +--- +ID: "2a65abb0-3123-469f-a603-5f3b1804713c" +Parent: "756fff26-90f2-4889-bace-da656e66b9c1" +Template: "013bc834-c0f6-4377-924e-0de185abfbe7" +Path: /sitecore/content/Home/MultiLanguage +DB: master +Languages: +- Language: de + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: "German Field1" + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: "German Field2" +- Language: en + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: "English Field1" + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: "English Field2" +- Language: fr + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: "French Field1" + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: "French Field2" +- Language: nl + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: "Dutch Field1" + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: "Dutch Field2" diff --git a/tests/YmlTransform.Tests/Data/Multi-Language.ymlexpected b/tests/YmlTransform.Tests/Data/Multi-Language.ymlexpected new file mode 100644 index 0000000..8a9b59a --- /dev/null +++ b/tests/YmlTransform.Tests/Data/Multi-Language.ymlexpected @@ -0,0 +1,47 @@ +--- +ID: "2a65abb0-3123-469f-a603-5f3b1804713c" +Parent: "756fff26-90f2-4889-bace-da656e66b9c1" +Template: "013bc834-c0f6-4377-924e-0de185abfbe7" +Path: /sitecore/content/Home/MultiLanguage +DB: master +Languages: +- Language: de + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: TransformedField1 + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: TransformedField2 +- Language: en + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: TransformedField1 + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: TransformedField2 +- Language: fr + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: TransformedField1 + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: TransformedField2 +- Language: nl + Versions: + - Version: 1 + Fields: + - ID: "00000000-0000-0000-0000-000000000000" + Hint: Field1 + Value: TransformedField1 + - ID: "00000000-0000-0000-0000-000000000001" + Hint: Field2 + Value: TransformedField2 diff --git a/tests/YmlTransform.Tests/Data/Multi-Language.ymltransform b/tests/YmlTransform.Tests/Data/Multi-Language.ymltransform new file mode 100644 index 0000000..bc0dffd --- /dev/null +++ b/tests/YmlTransform.Tests/Data/Multi-Language.ymltransform @@ -0,0 +1,18 @@ +[ + { + "FieldId": "00000000-0000-0000-0000-000000000000", + "Hint": "Field1", + "Languages": "*", + "Path": "/sitecore/content/Home/MultiLanguage", + "Type": "Languages", + "Value": "TransformedField1" + }, + { + "FieldId": "00000000-0000-0000-0000-000000000001", + "Hint": "Field2", + "Languages": "*", + "Path": "/sitecore/content/Home/MultiLanguage", + "Type": "Languages", + "Value": "TransformedField2" + } +] \ No newline at end of file diff --git a/tests/YmlTransform.Tests/Properties/AssemblyInfo.cs b/tests/YmlTransform.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..adb5daa --- /dev/null +++ b/tests/YmlTransform.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("YmlTransform.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("YmlTransform.Tests")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("bb5287ae-b720-4c65-80b0-15f4eb459ba4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/YmlTransform.Tests/YmlTransform.Tests.csproj b/tests/YmlTransform.Tests/YmlTransform.Tests.csproj new file mode 100644 index 0000000..75d8286 --- /dev/null +++ b/tests/YmlTransform.Tests/YmlTransform.Tests.csproj @@ -0,0 +1,105 @@ + + + + + + + Debug + AnyCPU + {BB5287AE-B720-4C65-80B0-15F4EB459BA4} + Library + Properties + YmlTransform.Tests + YmlTransform.Tests + v4.6.2 + 512 + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + ..\..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll + + + ..\..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + + + + + + + + + ..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll + + + ..\..\packages\xunit.assert.2.3.0\lib\netstandard1.1\xunit.assert.dll + + + ..\..\packages\xunit.extensibility.core.2.3.0\lib\netstandard1.1\xunit.core.dll + + + ..\..\packages\xunit.extensibility.execution.2.3.0\lib\net452\xunit.execution.desktop.dll + + + + + + + + + {00EC6644-0EBF-44A8-8EDF-F73D06787377} + YmlTransform + + + + + + Always + + + Always + + + Always + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + \ No newline at end of file diff --git a/tests/YmlTransform.Tests/YmlTransformerTests.cs b/tests/YmlTransform.Tests/YmlTransformerTests.cs new file mode 100644 index 0000000..68dadfb --- /dev/null +++ b/tests/YmlTransform.Tests/YmlTransformerTests.cs @@ -0,0 +1,44 @@ +using System.IO; +using System.Security.Cryptography; +using System.Text; +using Xunit; + +namespace YmlTransform.Tests +{ + public class YmlTransformerTests + { + [Fact] + public void TestMultiLanguageTranformation() + { + const string originalFile = @"Data\\Multi-Language.yml"; + const string expectedFile = @"Data\\Multi-Language.ymlexpected"; + + + YmlTransformer.TransformFile(originalFile, "Data\\Multi-Language.ymltransform"); + + var originalHash = GetFileHash(originalFile); + var expectedHash = GetFileHash(expectedFile); + + Assert.Equal(expectedHash, originalHash); + } + + public string GetFileHash(string filename) + { + var hash = new SHA1Managed(); + var clearBytes = File.ReadAllBytes(filename); + var hashedBytes = hash.ComputeHash(clearBytes); + return ConvertBytesToHex(hashedBytes); + } + + public string ConvertBytesToHex(byte[] bytes) + { + var sb = new StringBuilder(); + + for (var i = 0; i < bytes.Length; i++) + { + sb.Append(bytes[i].ToString("x")); + } + return sb.ToString(); + } + } +} diff --git a/tests/YmlTransform.Tests/app.config b/tests/YmlTransform.Tests/app.config new file mode 100644 index 0000000..c1ad690 --- /dev/null +++ b/tests/YmlTransform.Tests/app.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/YmlTransform.Tests/packages.config b/tests/YmlTransform.Tests/packages.config new file mode 100644 index 0000000..237e800 --- /dev/null +++ b/tests/YmlTransform.Tests/packages.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file