From 62ad2699c3dcb5f2d67939e67a1397c1f6235771 Mon Sep 17 00:00:00 2001 From: vikingcode Date: Sat, 21 Feb 2015 17:35:53 +1100 Subject: [PATCH] This sassy commit is all the rage this summer. Solves #192 - introduces Sass for CSS generation. Uses Libsassnet to provide the Sassyness. Switches out ILMerge for Fody/Costura. When handling unmanaged assemblies, this is the best solution. This required some modifications to how MEF was used. It uses a very specific version of Fody/Costura because of issues with VS15, I think. Please don't update it. --- .../Minification/SassTransform.cs | 88 +++++++++++++++++++ src/Pretzel.Logic/Pretzel.Logic.csproj | 11 ++- src/Pretzel.Logic/packages.config | 1 + src/Pretzel/FodyWeavers.xml | 9 ++ src/Pretzel/Pretzel.csproj | 25 +++--- src/Pretzel/Program.cs | 15 +++- src/Pretzel/packages.config | 2 + 7 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 src/Pretzel.Logic/Minification/SassTransform.cs create mode 100644 src/Pretzel/FodyWeavers.xml diff --git a/src/Pretzel.Logic/Minification/SassTransform.cs b/src/Pretzel.Logic/Minification/SassTransform.cs new file mode 100644 index 000000000..c7be61627 --- /dev/null +++ b/src/Pretzel.Logic/Minification/SassTransform.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.IO.Abstractions; +using System.Linq; +using HtmlAgilityPack; +using LibSassNet; +using Pretzel.Logic.Extensibility; +using Pretzel.Logic.Templating.Context; + +namespace Pretzel.Logic.Minification +{ + public class SassTransform : ITransform + { + private static readonly string[] ExternalProtocols = { "http", "https", "//" }; + +#pragma warning disable 0649 + private readonly IFileSystem fileSystem; +#pragma warning restore 0649 + + [ImportingConstructor] + public SassTransform(IFileSystem fileSystem) + { + this.fileSystem = fileSystem; + } + + private string filePath = string.Empty; + + private readonly ISassCompiler compiler = new SassCompiler(); + + public void Transform(SiteContext siteContext) + { + var shouldCompile = new List(); + //Process to see if the site has a CSS file that doesn't exist, and should be created from LESS files. + //This is "smarter" than just compiling all Less files, which will crash if they're part of a larger Less project + //ie, one file pulls in imports, individually they don't know about each other but use variables + foreach (var file in siteContext.Pages.Where(p => p.OutputFile.EndsWith(".html") && fileSystem.File.Exists(p.OutputFile))) + { + var doc = new HtmlDocument(); + var fileContents = fileSystem.File.ReadAllText(file.OutputFile); + doc.LoadHtml(fileContents); + + var nodes = doc.DocumentNode.SelectNodes("/html/head/link[@rel='stylesheet']"); + if (nodes != null) + foreach (HtmlNode link in nodes) + { + var cssfile = link.Attributes["href"].Value; + + // If the file is not local, ignore it + var matchingIgnoreProtocol = ExternalProtocols.FirstOrDefault(cssfile.StartsWith); + if (matchingIgnoreProtocol != null) + continue; + + //If the file exists, ignore it + if (fileSystem.File.Exists(Path.Combine(siteContext.OutputFolder, cssfile))) + continue; + + //If there is a CSS file that matches the name, ignore, could be another issue + if (siteContext.Pages.Any(p => p.OutputFile.Contains(cssfile))) + continue; + + + var n = cssfile.Replace(".css", ".scss"); + n = n.Replace('/', '\\'); + + var cssPageToCompile = siteContext.Pages.FirstOrDefault(f => f.OutputFile.Contains(n)); + if (cssPageToCompile != null && !shouldCompile.Contains(cssPageToCompile)) + { + shouldCompile.Add(cssPageToCompile); + } + } + } + + foreach (var less in shouldCompile) + { + filePath = less.OutputFile; + fileSystem.File.WriteAllText(less.OutputFile.Replace(".scss", ".css"), ProcessCss(siteContext, less.Filepath)); + fileSystem.File.Delete(less.OutputFile); + } + } + + public string ProcessCss(SiteContext siteContext, string file) + { + var x = compiler.CompileFile(file).CSS; + return x; + } + } +} diff --git a/src/Pretzel.Logic/Pretzel.Logic.csproj b/src/Pretzel.Logic/Pretzel.Logic.csproj index fb12b1146..ecc28b00e 100644 --- a/src/Pretzel.Logic/Pretzel.Logic.csproj +++ b/src/Pretzel.Logic/Pretzel.Logic.csproj @@ -23,6 +23,7 @@ DEBUG;TRACE prompt 4 + AnyCPU pdbonly @@ -49,6 +50,12 @@ ..\packages\HtmlAgilityPack.1.4.9\lib\Net40\HtmlAgilityPack.dll + + ..\packages\libsassnet.3.0.1.1\lib\net40\LibSass.x86.dll + + + ..\packages\libsassnet.3.0.1.1\lib\net40\libsassnet.dll + ..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll @@ -113,6 +120,7 @@ + True @@ -286,5 +294,4 @@ --> - - + \ No newline at end of file diff --git a/src/Pretzel.Logic/packages.config b/src/Pretzel.Logic/packages.config index 0bde3e7db..ffa9f7ca9 100644 --- a/src/Pretzel.Logic/packages.config +++ b/src/Pretzel.Logic/packages.config @@ -5,6 +5,7 @@ + diff --git a/src/Pretzel/FodyWeavers.xml b/src/Pretzel/FodyWeavers.xml new file mode 100644 index 000000000..78fcdfe03 --- /dev/null +++ b/src/Pretzel/FodyWeavers.xml @@ -0,0 +1,9 @@ + + + + + LibSass.x86 + + + + \ No newline at end of file diff --git a/src/Pretzel/Pretzel.csproj b/src/Pretzel/Pretzel.csproj index 463cf77f3..b9b32ca1e 100644 --- a/src/Pretzel/Pretzel.csproj +++ b/src/Pretzel/Pretzel.csproj @@ -16,6 +16,7 @@ 512 ..\ true + 46fc839a x86 @@ -156,21 +157,21 @@ + + Designer + - - - - - - - + + - - + \ No newline at end of file diff --git a/src/Pretzel/Program.cs b/src/Pretzel/Program.cs index 81d6bba70..716599a92 100644 --- a/src/Pretzel/Program.cs +++ b/src/Pretzel/Program.cs @@ -110,8 +110,19 @@ public void Compose() { try { - var first = new AssemblyCatalog(Assembly.GetExecutingAssembly()); - catalog = new AggregateCatalog(first); + var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); + + loadedAssemblies + .SelectMany(x => x.GetReferencedAssemblies()) + .Distinct() + .Where(y => loadedAssemblies.Any((a) => a.FullName == y.FullName) == false) + .ToList() + .ForEach(x => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(x))); + + catalog = new AggregateCatalog(); + + foreach (var l in loadedAssemblies) + catalog.Catalogs.Add(new AssemblyCatalog(l)); container = new CompositionContainer(catalog); var batch = new CompositionBatch(); diff --git a/src/Pretzel/packages.config b/src/Pretzel/packages.config index 26338eadd..389e515ee 100644 --- a/src/Pretzel/packages.config +++ b/src/Pretzel/packages.config @@ -1,6 +1,8 @@  + +