diff --git a/src/Microsoft.VisualStudio.SlowCheetah/Transformer/IniTransformer.cs b/src/Microsoft.VisualStudio.SlowCheetah/Transformer/IniTransformer.cs new file mode 100644 index 00000000..e09f5530 --- /dev/null +++ b/src/Microsoft.VisualStudio.SlowCheetah/Transformer/IniTransformer.cs @@ -0,0 +1,205 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.SlowCheetah +{ + using System; + using System.Collections.Generic; + using System.IO; + using Microsoft.VisualStudio.Jdt; + + /// + /// Transforms Ini files + /// + public class IniTransformer : ITransformer + { + private IJsonTransformationLogger logger; + + /// + /// Initializes a new instance of the class. + /// + public IniTransformer() + { + } + + /// + /// Initializes a new instance of the class with an external logger + /// + /// The external logger + public IniTransformer(ITransformationLogger logger) + { + if (logger == null) + { + throw new ArgumentNullException(nameof(logger)); + } + + this.logger = new JsonShimLogger(logger); + } + + /// + public void CreateTransformFile(string sourcePath, string transformPath, bool overwrite) + { + if (string.IsNullOrWhiteSpace(sourcePath)) + { + throw new ArgumentNullException(nameof(sourcePath)); + } + + if (string.IsNullOrWhiteSpace(transformPath)) + { + throw new ArgumentNullException(nameof(transformPath)); + } + + if (!File.Exists(sourcePath)) + { + throw new FileNotFoundException(Resources.Resources.ErrorMessage_SourceFileNotFound, sourcePath); + } + + // If the file should be overwritten or if it doesn't exist, we create it + if (overwrite || !File.Exists(transformPath)) + { + var encoding = TransformUtilities.GetEncoding(sourcePath); + File.WriteAllText(transformPath, string.Empty, encoding); + } + } + + /// + public bool IsFileSupported(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentNullException(nameof(filePath)); + } + + if (!File.Exists(filePath)) + { + throw new FileNotFoundException(Resources.Resources.ErrorMessage_FileNotFound, filePath); + } + + return Path.GetExtension(filePath).Equals(".ini", StringComparison.OrdinalIgnoreCase); + } + + /// + public bool Transform(string sourcePath, string transformPath, string destinationPath) + { + if (string.IsNullOrWhiteSpace(sourcePath)) + { + throw new ArgumentException($"{nameof(sourcePath)} cannot be null or whitespace"); + } + + if (string.IsNullOrWhiteSpace(transformPath)) + { + throw new ArgumentException($"{nameof(transformPath)} cannot be null or whitespace"); + } + + if (string.IsNullOrWhiteSpace(destinationPath)) + { + throw new ArgumentException($"{nameof(destinationPath)} cannot be null or whitespace"); + } + + if (!File.Exists(sourcePath)) + { + throw new FileNotFoundException(Resources.Resources.ErrorMessage_SourceFileNotFound, sourcePath); + } + + if (!File.Exists(transformPath)) + { + throw new FileNotFoundException(Resources.Resources.ErrorMessage_TransformFileNotFound, transformPath); + } + + try + { + Dictionary transformDictionary = new Dictionary(); + string currentRoot = null; + string[] keyPair = null; + + if (!System.IO.File.Exists(sourcePath) || !System.IO.File.Exists(transformPath)) + { + return false; + } + + // Collect what we need to replace + using (StreamReader iniFile = new StreamReader(transformPath)) + { + string strLine = iniFile.ReadLine(); + while (strLine != null) + { + if (!string.IsNullOrEmpty(strLine)) + { + if (strLine.StartsWith("[") && strLine.EndsWith("]")) + { + currentRoot = strLine.Substring(1, strLine.Length - 2); + } + else if (!strLine.StartsWith(";") && !strLine.StartsWith("#")) + { + keyPair = strLine.Split(new char[] { '=' }, 2); + if (keyPair.Length > 1 && !transformDictionary.ContainsKey(currentRoot + "-" + keyPair[0])) + { + transformDictionary.Add(currentRoot + "-" + keyPair[0], keyPair[1]); + } + } + } + strLine = iniFile.ReadLine(); + } + } + + // read the source file and replace lines where is necessary + using (StreamReader iniFile = new StreamReader(sourcePath)) + { + using (StreamWriter destFile = new StreamWriter(destinationPath)) + { + string strLine = iniFile.ReadLine(); + while (strLine != null) + { + if (!string.IsNullOrEmpty(strLine)) + { + if (strLine.StartsWith("[") && strLine.EndsWith("]")) + { + currentRoot = strLine.Substring(1, strLine.Length - 2); + } + else if (!strLine.StartsWith(";") && !strLine.StartsWith("#")) + { + keyPair = strLine.Split(new char[] { '=' }, 2); + if (keyPair.Length > 1 && transformDictionary.ContainsKey(currentRoot + "-" + keyPair[0])) + { + strLine = keyPair[0] + "=" + transformDictionary[currentRoot + "-" + keyPair[0]]; + } + } + destFile.WriteLine(strLine); + } + else + { + destFile.WriteLine(strLine); + } + + strLine = iniFile.ReadLine(); + } + } + } + + return true; + } + catch + { + // JDT exceptions are handled by it's own logger + return false; + } + } + + /// + public ITransformer WithLogger(ITransformationLogger logger) + { + if (logger == this.logger) + { + return this; + } + else if (logger == null) + { + return new IniTransformer(); + } + else + { + return new IniTransformer(logger); + } + } + } +} diff --git a/src/Microsoft.VisualStudio.SlowCheetah/Transformer/TransformerFactory.cs b/src/Microsoft.VisualStudio.SlowCheetah/Transformer/TransformerFactory.cs index 2d7c506c..15937683 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah/Transformer/TransformerFactory.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah/Transformer/TransformerFactory.cs @@ -18,6 +18,7 @@ public static class TransformerFactory { new JsonTransformer(), new XmlTransformer(), + new IniTransformer() }; ///