/// <summary>Gets the md5 hash for the current content item.</summary>
 /// <param name="context">The context.</param>
 /// <returns>The md5 hash as a string.</returns>
 internal string GetContentHash(IWebGreaseContext context)
 {
     return(this.contentHash ??
            (this.contentHash = ContentItemType == ContentItemType.Value
             ? context.GetValueHash(this.Content)
             : context.GetFileHash(this.AbsoluteContentPath)));
 }
        /// <summary>Begins the section, create a new section and returns it.</summary>
        /// <param name="context">The context.</param>
        /// <param name="cacheCategory">The cache category.</param>
        /// <param name="uniqueKey">The unique Key.</param>
        /// <param name="parentCacheSection">The parent cache section.</param>
        /// <param name="autoLoad">The auto Load.</param>
        /// <returns>The <see cref="CacheSection"/>.</returns>
        public static CacheSection Begin(IWebGreaseContext context, string cacheCategory, string uniqueKey, ICacheSection parentCacheSection = null, bool autoLoad = true)
        {
            var cacheSection = new CacheSection
            {
                parent        = parentCacheSection as CacheSection,
                cacheCategory = cacheCategory,
                context       = context,
                UniqueKey     = uniqueKey
            };

            cacheSection.absolutePath = context.Cache.GetAbsoluteCacheFilePath(cacheSection.cacheCategory, context.GetValueHash(cacheSection.UniqueKey) + ".cache.json");

            if (cacheSection.parent != null)
            {
                cacheSection.parent.AddChildCacheSection(cacheSection);
            }

            EnsureCachePath(context, cacheCategory);

            if (autoLoad)
            {
                cacheSection.Load();
            }

            return(cacheSection);
        }
        public ContentItem Process(IWebGreaseContext context, ContentItem contentItem, PreprocessingConfig preprocessingConfig, bool minimalOutput)
        {
            var settingsMinimalOutput = preprocessingConfig != null && preprocessingConfig.Element != null && (bool?)preprocessingConfig.Element.Attribute("minimalOutput") == true;
            var relativeContentPath   = contentItem.RelativeContentPath;

            context.Log.Information("Sass: Processing contents for file {0}".InvariantFormat(relativeContentPath));

            context.SectionedAction(SectionIdParts.Preprocessing, SectionIdParts.Process, "Sass")
            .Execute(
                () =>
            {
                var sassCacheImportsSection = context.Cache.CurrentCacheSection;

                string fileToProcess = null;
                var isTemp           = false;
                try
                {
                    var workingDirectory = Path.IsPathRooted(relativeContentPath)
                                                       ? Path.GetDirectoryName(relativeContentPath)
                                                       : context.GetWorkingSourceDirectory(relativeContentPath);

                    var content = ParseImports(contentItem.Content, workingDirectory, sassCacheImportsSection, minimalOutput || settingsMinimalOutput);

                    var currentContentHash = context.GetValueHash(content);

                    var contentIsUnchangedFromDisk = !string.IsNullOrWhiteSpace(contentItem.AbsoluteDiskPath) &&
                                                     File.Exists(contentItem.AbsoluteDiskPath) &&
                                                     context.GetFileHash(contentItem.AbsoluteDiskPath).Equals(currentContentHash);

                    if (contentIsUnchangedFromDisk)
                    {
                        fileToProcess = contentItem.AbsoluteDiskPath;
                    }
                    else if (!string.IsNullOrWhiteSpace(relativeContentPath))
                    {
                        fileToProcess = Path.Combine(context.Configuration.SourceDirectory ?? string.Empty, relativeContentPath);

                        fileToProcess       = PrependToExtension(fileToProcess, ".imports");
                        relativeContentPath = PrependToExtension(relativeContentPath, ".imports");

                        if (!File.Exists(fileToProcess) || !context.GetFileHash(fileToProcess).Equals(currentContentHash))
                        {
                            File.WriteAllText(fileToProcess, content);
                        }
                    }
                    else
                    {
                        isTemp        = true;
                        fileToProcess = Path.GetTempFileName() + Path.GetExtension(relativeContentPath);
                        File.WriteAllText(fileToProcess, content);
                    }

                    content = ProcessFile(fileToProcess, workingDirectory, relativeContentPath, context);

                    contentItem = content != null ? ContentItem.FromContent(content, contentItem) : null;

                    return(true);
                }
                finally
                {
                    if (isTemp && !string.IsNullOrWhiteSpace(fileToProcess))
                    {
                        try
                        {
                            File.Delete(fileToProcess);
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
            });

            return(contentItem);
        }