From 46efca2e30e357f8f0036fe5bb099163d0d8621d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zsolt=20Feh=C3=A9r?= Date: Fri, 23 Oct 2015 13:34:11 +0200 Subject: [PATCH] Implement folder support. --- src/WebCompiler/Config/Config.cs | 77 ++++++++++++++++++- src/WebCompiler/Config/ConfigHandler.cs | 14 +++- .../Config/ConfigHandlerTest.cs | 2 + .../JSON/compilerconfig-schema.json | 18 ++--- 4 files changed, 96 insertions(+), 15 deletions(-) diff --git a/src/WebCompiler/Config/Config.cs b/src/WebCompiler/Config/Config.cs index a2a1d8e5..28388516 100644 --- a/src/WebCompiler/Config/Config.cs +++ b/src/WebCompiler/Config/Config.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Linq; +using System.Collections.Generic; using System.IO; using Newtonsoft.Json; @@ -27,6 +28,18 @@ public class Config [JsonProperty("inputFile")] public string InputFile { get; set; } + /// + /// The relative file path to the output files. + /// + [JsonProperty("outputFiles")] + public string OutputFiles { get; set; } + + /// + /// The relative file path to the input files. + /// + [JsonProperty("inputFiles")] + public string InputFiles { get; set; } + /// /// Settings for the minification. /// @@ -58,8 +71,7 @@ public class Config /// public FileInfo GetAbsoluteInputFile() { - string folder = new FileInfo(FileName).DirectoryName; - return new FileInfo(Path.Combine(folder, InputFile.Replace("/", "\\"))); + return new FileInfo(GetAbsolutePath(InputFile)); } /// @@ -67,8 +79,22 @@ public FileInfo GetAbsoluteInputFile() /// public FileInfo GetAbsoluteOutputFile() { + return new FileInfo(GetAbsolutePath(OutputFile)); + } + + private string GetAbsolutePath(string relativePath) + { + string folder = new FileInfo(FileName).DirectoryName; + return Path.Combine(folder, relativePath.Replace("/", "\\")); + } + + private string GetRelativePath(string absolutePath) + { + if (absolutePath == null) + return null; + string folder = new FileInfo(FileName).DirectoryName; - return new FileInfo(Path.Combine(folder, OutputFile.Replace("/", "\\"))); + return absolutePath.Replace(folder, string.Empty).TrimStart('\\').Replace("\\", "/"); } /// @@ -85,6 +111,49 @@ internal bool CompilationRequired() return input.LastWriteTimeUtc > output.LastWriteTimeUtc; } + internal IEnumerable ExpandConfig() + { + string inputFiles = InputFiles; + string outputFiles = OutputFiles; + + InputFiles = OutputFiles = null; + + if (!string.IsNullOrEmpty(InputFile) && !string.IsNullOrEmpty(OutputFile)) + { + yield return this; + } + + if (string.IsNullOrEmpty(inputFiles) || string.IsNullOrEmpty(outputFiles)) + { + yield break; + } + + inputFiles = GetAbsolutePath(inputFiles); + outputFiles = GetAbsolutePath(outputFiles); + + string inputFolder = Path.GetDirectoryName(inputFiles); + string inputFilePattern = Path.GetFileName(inputFiles); + string outputFolder = Path.GetDirectoryName(outputFiles); + string outputFilePattern = Path.GetFileName(outputFiles); + + foreach (var filePath in Directory.GetFiles(inputFolder, inputFilePattern)) + { + var fileConfig = Clone(); + fileConfig.InputFile = GetRelativePath(filePath); + fileConfig.OutputFile = GetRelativePath(Path.Combine(outputFolder, + Path.ChangeExtension(Path.GetFileName(filePath), Path.GetExtension(outputFilePattern)))); + yield return fileConfig; + } + } + + private Config Clone() + { + var clone = (Config)MemberwiseClone(); + clone.Minify = Minify.AsEnumerable().ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + clone.Options = Options.AsEnumerable().ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + return clone; + } + /// /// Determines if the object is equals to the other object. /// diff --git a/src/WebCompiler/Config/ConfigHandler.cs b/src/WebCompiler/Config/ConfigHandler.cs index 260f06af..18185eef 100644 --- a/src/WebCompiler/Config/ConfigHandler.cs +++ b/src/WebCompiler/Config/ConfigHandler.cs @@ -18,7 +18,7 @@ public class ConfigHandler /// The compiler config object to add to the configration file. public void AddConfig(string fileName, Config config) { - IEnumerable existing = GetConfigs(fileName); + IEnumerable existing = GetVerbatimConfigs(fileName); List configs = new List(); configs.AddRange(existing); configs.Add(config); @@ -39,7 +39,7 @@ public void AddConfig(string fileName, Config config) /// public void RemoveConfig(Config configToRemove) { - IEnumerable configs = GetConfigs(configToRemove.FileName); + IEnumerable configs = GetVerbatimConfigs(configToRemove.FileName); List newConfigs = new List(); if (configs.Contains(configToRemove)) @@ -95,6 +95,16 @@ public void CreateDefaultsFile(string fileName) /// A relative or absolute file path to the configuration file. /// A list of Config objects. public static IEnumerable GetConfigs(string fileName) + { + IEnumerable configs = GetVerbatimConfigs(fileName); + + if (configs != null && configs.Any()) + configs = configs.SelectMany(c => c.ExpandConfig()).Distinct().ToList(); + + return configs; + } + + private static IEnumerable GetVerbatimConfigs(string fileName) { FileInfo file = new FileInfo(fileName); diff --git a/src/WebCompilerTest/Config/ConfigHandlerTest.cs b/src/WebCompilerTest/Config/ConfigHandlerTest.cs index 700d80f1..23769ca2 100644 --- a/src/WebCompilerTest/Config/ConfigHandlerTest.cs +++ b/src/WebCompilerTest/Config/ConfigHandlerTest.cs @@ -35,6 +35,8 @@ public void AddConfig() var newConfig = new WebCompiler.Config(); const string newInputFileName = "newInputFile"; newConfig.InputFile = newInputFileName; + const string newOutputFileName = "newOutputFile"; + newConfig.OutputFile = newOutputFileName; _handler.AddConfig(processingConfigFile, newConfig); diff --git a/src/WebCompilerVsix/JSON/compilerconfig-schema.json b/src/WebCompilerVsix/JSON/compilerconfig-schema.json index 7b42f8e6..578f280f 100644 --- a/src/WebCompilerVsix/JSON/compilerconfig-schema.json +++ b/src/WebCompilerVsix/JSON/compilerconfig-schema.json @@ -87,24 +87,24 @@ }, "config": { - "required": [ "outputFile", "inputFile" ], - - "properties": { + "properties": { "includeInProject": { "description": "Set to true to include the output file in the project. Doesn't work in some Visual Studio project types like ASP.NET 5 applications.", "type": "boolean", "default": true }, + "inputFiles": { "type": "string" }, "inputFile": { - "description": "One or more relative file names to bundle.", - "type": "string", - "format": "compiler_relativepath" + "description": "One or more relative file names to bundle.", + "type": "string", + "format": "compiler_relativepath" }, "minify": { - "description": "Specify options for minification of the output file.", - "type": "object", - "allOf": [ { "$ref": "compilerdefaults-schema.json#/definitions/baseMinify" } ] + "description": "Specify options for minification of the output file.", + "type": "object", + "allOf": [ { "$ref": "compilerdefaults-schema.json#/definitions/baseMinify" } ] }, + "outputFiles": { "type": "string" }, "outputFile": { "description": "The relative path to the desired output file name.", "type": "string",