/// <summary>The method called from the regex replace to replace the matched wgInclude() statements.</summary> /// <param name="match">The regex match</param> /// <param name="workingFolder">The working folder from which to determine relative path's in the include.</param> /// <param name="cacheSection">The cache Section.</param> /// <param name="minimalOutput">Is the goal to have the most minimal output (true skips lots of comments)</param> /// <returns>The contents of the file to replace, with a /* WGINCLUDE [fullFilePath] */ header on top.</returns> private static string ReplaceInputs(Match match, string workingFolder, ICacheSection cacheSection, bool minimalOutput) { var fileOrPath = Path.Combine(workingFolder, match.Groups["fileOrPath"].Value.Trim()); var inputSpec = new InputSpec { IsOptional = true, Path = fileOrPath }; if (Directory.Exists(fileOrPath)) { inputSpec.SearchPattern = match.Groups["searchPattern"].Value.Trim(); } cacheSection.AddSourceDependency(inputSpec); var result = string.Empty; foreach (var file in inputSpec.GetFiles()) { if (!minimalOutput) { result += "/* WGINCLUDE: {0} */\r\n".InvariantFormat(file); } result += File.ReadAllText(file) + "\r\n"; } return(result); }
/// <summary>Hash the images.</summary> /// <param name="cssContent">The css content.</param> /// <param name="imageHasher">The image Hasher.</param> /// <param name="cacheSection">The cache section.</param> /// <param name="threadContext">The context.</param> /// <param name="sourceImages">The source Images.</param> /// <param name="missingImage">The missing Image.</param> /// <returns>The css with hashed images.</returns> private static Tuple <string, IEnumerable <ContentItem> > HashImages(string cssContent, FileHasherActivity imageHasher, ICacheSection cacheSection, IWebGreaseContext threadContext, IDictionary <string, string> sourceImages, string missingImage) { return(threadContext.SectionedAction(SectionIdParts.MinifyCssActivity, SectionIdParts.ImageHash).Execute(() => { var contentImagesToHash = new HashSet <string>(); var hashedContentItems = new List <ContentItem>(); var hashedImages = new Dictionary <string, string>(); cssContent = UrlHashRegexPattern.Replace( cssContent, match => { var urlToHash = match.Groups["url"].Value; var extraInfo = match.Groups["extra"].Value; if (ResourcesResolver.LocalizationResourceKeyRegex.IsMatch(urlToHash)) { return match.Value; } var normalizedHashUrl = urlToHash.NormalizeUrl(); var imageContentFile = sourceImages.TryGetValue(normalizedHashUrl); if (imageContentFile == null && !string.IsNullOrWhiteSpace(missingImage)) { imageContentFile = sourceImages.TryGetValue(missingImage); } if (imageContentFile == null) { throw new BuildWorkflowException("Could not find a matching source image for url: {0}".InvariantFormat(urlToHash)); } if (contentImagesToHash.Add(normalizedHashUrl)) { // Add the image as end result var imageContentItem = ContentItem.FromFile(imageContentFile, normalizedHashUrl); imageContentItem = imageHasher.Hash(imageContentItem); cacheSection.AddSourceDependency(imageContentFile); hashedContentItems.Add(imageContentItem); imageContentFile = Path.Combine( imageHasher.BasePrefixToAddToOutputPath ?? Path.AltDirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), imageContentItem.RelativeHashedContentPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); hashedImages.Add(normalizedHashUrl, imageContentFile); } else { imageContentFile = hashedImages[normalizedHashUrl]; } return "url(" + imageContentFile + extraInfo + ")"; }); return Tuple.Create(cssContent, (IEnumerable <ContentItem>)hashedContentItems); })); }
/// <summary>Sets the import source dependencies.</summary> /// <param name="fileContent">The file content.</param> /// <param name="workingFolder">The working folder.</param> /// <param name="cacheSection">The cache section.</param> private static void SetImportSourceDependencies(string fileContent, string workingFolder, ICacheSection cacheSection) { var matches = ImportPattern.Matches(fileContent); foreach (Match match in matches) { var path = Path.Combine(workingFolder, match.Groups["path"].Value); var fi = new FileInfo(path); cacheSection.AddSourceDependency(path); if (fi.Exists) { SetImportSourceDependencies(File.ReadAllText(fi.FullName), fi.DirectoryName, cacheSection); } } }
/// <summary>The replace imports.</summary> /// <param name="match">The match.</param> /// <param name="workingFolder">The working folder.</param> /// <param name="cacheSection">The cache Section.</param> /// <param name="minimalOutput">Is the goal to have the most minimal output (true skips lots of comments)</param> /// <returns>The replaced imports.</returns> private static string ReplaceImports(Match match, string workingFolder, ICacheSection cacheSection, bool minimalOutput) { var path = match.Groups["path"].Value; string pattern = null; var pathParts = path.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries).ToList(); var possiblePattern = pathParts.LastOrDefault(); if (!string.IsNullOrEmpty(possiblePattern) && possiblePattern.Contains("*")) { pattern = possiblePattern; pathParts.RemoveAt(pathParts.Count - 1); } var pathInfo = new DirectoryInfo(Path.Combine(workingFolder, string.Join("\\", pathParts))); cacheSection.AddSourceDependency(new InputSpec { IsOptional = true, Path = pathInfo.FullName, SearchOption = SearchOption.TopDirectoryOnly, SearchPattern = pattern }); if (!pathInfo.Exists) { return(string.Empty); } var files = !string.IsNullOrWhiteSpace(pattern) ? Directory.GetFiles(pathInfo.FullName, pattern) : Directory.GetFiles(pathInfo.FullName); return ((minimalOutput ? string.Empty : GetImportsComment(path, string.Empty)) + string.Join( " ", files .Select(file => MakeRelativePath(workingFolder, file)) .Select(relativeFile => "{0}\r\n@import \"{1}\";".InvariantFormat( minimalOutput ? string.Empty : "\r\n" + GetImportsComment(path, Path.GetFileName(relativeFile)), relativeFile.Replace("\\", "/"))))); }