static void CreateThemes(string sourcePath, string version, string outputPath) { Directory.CreateDirectory(outputPath); var lessCache = new CompiledLessCache(sourcePath); lessCache.Inflate(PersistentCache.Instance); foreach (var distributionName in LessRegistry.CssDistributions.Keys) { var aggregate = LessAggregation.EnumerateAllItems(sourcePath, distributionName); foreach (var item in aggregate) { using (var stream = File.Create(Path.Combine(outputPath, item.CssFile.GetFileName()))) using (var writer = new StreamWriter(stream)) { writer.WriteLine(LicenseHeaderHelper.FormatForCssDistribution(distributionName, version)); foreach (var segment in item.Segments) { writer.WriteLine(lessCache.GetCssForSegment(segment.Key)); } } } } CopyFonts(sourcePath, outputPath, "icons"); CopyFonts(sourcePath, outputPath, "fonts"); }
public string KnownCssFiles() { var paths = from distributionName in LessRegistry.CssDistributions.Keys from item in LessAggregation.EnumerateAllItems(Utils.GetStylesPath(), distributionName) select item.CssFile.GetFileName(); Response.ContentType = "text/javascript"; return("window.knownCssFiles = " + JsonConvert.SerializeObject(paths)); }
public void Inflate(PersistentCache persistentCache) { var knownSegments = new HashSet <string>(); var parallelTasks = new List <Task>(); foreach (var distributionName in LessRegistry.CssDistributions.Keys) { foreach (var item in LessAggregation.EnumerateAllItems(_sourcePath, distributionName)) { LessAggregation.CheckLessDuplicates(item); foreach (var segment in item.Segments) { if (knownSegments.Contains(segment.Key)) { continue; } knownSegments.Add(segment.Key); parallelTasks.Add(new Task(delegate() { var paths = segment.LessFiles.Select(i => Path.Combine(_sourcePath, i)); var bag = persistentCache.Get(new[] { "css", segment.Key }, paths, delegate() { if (distributionName == LessRegistry.CSS_DISTRIBUTION_DEFAULT) { CheckUnusedLessConsts(paths); } var css = LessAggregation.CompileLessPaths(paths); css = ImageInliner.InlineImages(css, _sourcePath); css = CssHelper.StripCommentsOnly(css); return(new Dictionary <string, string> { { "_", css } }); }); _SegmentCache[segment.Key] = bag["_"]; })); } } } foreach (var t in parallelTasks) { t.Start(); if (Utils.IsDocker()) { // limit CPU usage in Docker builds t.Wait(); } } Task.WaitAll(parallelTasks.ToArray()); }
public void KnownCssFiles() { var paths = from distributionName in LessRegistry.CssDistributions.Keys from item in LessAggregation.EnumerateAllItems(Utils.GetStylesPath(), distributionName) select item.CssFile.GetFileName(); Response.ContentType = "text/javascript"; using (var writer = new StreamWriter(Response.Body)) { writer.Write("window.knownCssFiles = "); writer.Write(JsonConvert.SerializeObject(paths)); } }
static void CheckUnusedLessConsts(IEnumerable <string> paths) { var lessContent = new StringBuilder(); foreach (var path in paths) { lessContent.AppendLine(LessAggregation.InlineImports(path)); } var lessContentWithoutComments = CssHelper.StripCommentsOnly(lessContent.ToString()); var matches = Regex.Matches(lessContentWithoutComments, @"@\{?(\w[\w-]*)\}?", RegexOptions.Multiline); var counts = new Dictionary <string, int>(); var cssConst = new[] { "charset", "font-face", "import", "media", "page" }; var multiWidgetConsts = FindMultiWidgetConsts(lessContentWithoutComments); foreach (Match match in matches) { var text = match.Groups[1].Value; if (cssConst.Contains(text)) { continue; } if (!counts.ContainsKey(text)) { counts[text] = 1; } else { counts[text]++; } } var failures = counts .Where(entry => entry.Value == 1) .Where(entry => !multiWidgetConsts.Contains(StripFirstWord(entry.Key))) .ToArray(); if (failures.Length > 0) { foreach (var entry in failures) { Console.WriteLine("Warning: " + entry.Key + " is unused"); } throw new Exception("Unused LESS consts were found"); } }
LessAggregation.Item CreateAggregationItem(IQueryCollection queryString) { var distributionName = queryString["d"]; var isCommon = queryString.ContainsKey("common"); if (isCommon) { return(LessAggregation.CreateCommonItem(distributionName)); } var themeName = queryString["t"]; var colorSchemeName = queryString["cs"]; var sizeSchemeName = queryString["ss"]; var theme = LessRegistry.KnownThemeMap[themeName]; return(LessAggregation.CreateThemeItem(_sourcePath, distributionName, theme, colorSchemeName, sizeSchemeName)); }
static void CreateThemes(string sourcePath, string version, string outputPath) { Directory.CreateDirectory(outputPath); var lessCache = new CompiledLessCache(sourcePath); lessCache.Inflate(PersistentCache.Instance); foreach (var distributionName in LessRegistry.CssDistributions.Keys) { var aggregate = LessAggregation.EnumerateAllItems(sourcePath, distributionName); foreach (var item in aggregate) { using (var stream = File.Create(Path.Combine(outputPath, item.CssFile.GetFileName()))) using (var writer = new StreamWriter(stream)) { writer.WriteLine(LicenseHeaderHelper.FormatForCssDistribution(distributionName, version)); foreach (var segment in item.Segments) { writer.WriteLine(lessCache.GetCssForSegment(segment.Key)); } } } } var iconsSrcFolder = LessRegistry.GetIconsPath(sourcePath); var iconsDestFolder = Path.Combine(outputPath, "icons"); Directory.GetFiles(iconsSrcFolder, "*.*", SearchOption.AllDirectories).ToList() .ForEach(fileName => { string relativePath = fileName.Remove(0, iconsSrcFolder.Length); string destFileName = iconsDestFolder + relativePath; if (!Directory.Exists(Path.GetDirectoryName(destFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(destFileName)); } File.Copy(fileName, destFileName, true); }); }
public void ProcessRequest(IQueryCollection queryString, Stream responseBody) { var allLessPaths = from segment in CreateAggregationItem(queryString).Segments from fileName in segment.LessFiles select Path.Combine(_sourcePath, fileName); var css = LessAggregation.CompileLessPaths(allLessPaths); css = NormalizeUrls(css); if (queryString.ContainsKey("disable_font_face")) { css = css.Replace("@font-face", "@disabled-font-face"); } using (var writer = new StreamWriter(responseBody)) { writer.Write(css); } }