Ejemplo n.º 1
0
 /// <summary>The get processors.</summary>
 /// <param name="contentItem">The content item.</param>
 /// <param name="preprocessConfig">The preprocess config.</param>
 /// <returns>The list of preprocessors that applies to the content item.</returns>
 internal IPreprocessingEngine[] GetProcessors(ContentItem contentItem, PreprocessingConfig preprocessConfig)
 {
     return(preprocessConfig.PreprocessingEngines
            .SelectMany(ppe => this.registeredPreprocessingEngines.Where(rppe => rppe.Name.Equals(ppe, StringComparison.OrdinalIgnoreCase)))
            .Where(pptu => pptu.CanProcess(this.context, contentItem, preprocessConfig))
            .ToArray());
 }
Ejemplo n.º 2
0
        public void WithPreprocessorFiles()
        {
            var preprocessingConfig = new PreprocessingConfig(XElement.Parse("<Preprocessing><Engines>sass</Engines></Preprocessing>"));

            var sourceDirectory   = Path.Combine(TestDeploymentPaths.TestDirectory, @"WebGrease.Tests\AssemblerActivityTest\");
            var assemblerActivity = new AssemblerActivity(new WebGreaseContext(new WebGreaseConfiguration()));

            assemblerActivity.PreprocessingConfig = preprocessingConfig;

            assemblerActivity.Inputs.Add(new InputSpec {
                Path = Path.Combine(sourceDirectory, @"Input\Case4\Stylesheet1.scss")
            });
            assemblerActivity.Inputs.Add(new InputSpec {
                Path = Path.Combine(sourceDirectory, @"Input\Case4\Stylesheet2.css")
            });
            assemblerActivity.OutputFile = Path.Combine(sourceDirectory, @"Output\Case4\case4.css");
            assemblerActivity.Execute();

            // Assertions
            var outputFilePath = assemblerActivity.OutputFile;

            Assert.IsTrue(File.Exists(outputFilePath));
            var text = File.ReadAllText(outputFilePath);

            Assert.IsTrue(!string.IsNullOrWhiteSpace(text));
            Assert.IsTrue(text.Contains("Stylesheet1.scss  */"));
            Assert.IsTrue(text.Contains("font-size: %MetroSdk.BaseFontSize%;"));
            Assert.IsTrue(text.Contains("@media screen and (min-width: %MetroSdk.Mq.MinWidth%) and (max-width: %MetroSdk.Mq.MaxWidth%) {"));
            Assert.IsTrue(text.Contains("Stylesheet2.css  */"));
            Assert.IsTrue(text.Contains(".asome {\r\n    color: blue;\r\n}"));
        }
Ejemplo n.º 3
0
        /// <summary>This method will be called to check if the processor believes it can handle the file based on the filename.</summary>
        /// <param name="context">The context.</param>
        /// <param name="contentItem">The full path to the file.</param>
        /// <param name="preprocessConfig">The configuration</param>
        /// <returns>If it thinks it can process it.</returns>
        public bool CanProcess(IWebGreaseContext context, ContentItem contentItem, PreprocessingConfig preprocessConfig = null)
        {
            var sassConfig = GetConfig(preprocessConfig);
            var extension  = Path.GetExtension(contentItem.RelativeContentPath);

            return
                (extension != null &&
                 (extension.EndsWith(sassConfig.SassExtension, StringComparison.OrdinalIgnoreCase) ||
                  extension.EndsWith(sassConfig.ScssExtension, StringComparison.OrdinalIgnoreCase)));
        }
Ejemplo n.º 4
0
        /// <summary>Determines if the processor can parse the filetype, always true for this engine.</summary>
        /// <param name="context">The context.</param>
        /// <param name="contentItem">The full filename</param>
        /// <param name="preprocessConfig">The pre processing config</param>
        /// <returns>True if it can process it, otherwise false.</returns>
        public bool CanProcess(IWebGreaseContext context, ContentItem contentItem, PreprocessingConfig preprocessConfig = null)
        {
            if (preprocessConfig != null && preprocessConfig.Element != null)
            {
                var extensions = (string)preprocessConfig.Element.Attribute("wgincludeextensions")
                                 ?? (string)preprocessConfig.Element.Element("wgincludeextensions");

                if (!string.IsNullOrWhiteSpace(extensions))
                {
                    return(extensions
                           .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                           .Any(wgIncludeExtension => contentItem.RelativeContentPath.EndsWith(wgIncludeExtension, StringComparison.OrdinalIgnoreCase)));
                }
            }

            return(true);
        }
Ejemplo n.º 5
0
        public SassConfig(PreprocessingConfig config)
            : this()
        {
            if (config != null)
            {
                var element = config.Element;
                this.SassExtension =
                    ((string)element.Element(SassExtensionName)).AsNullIfWhiteSpace()
                    ?? ((string)element.Attribute(SassExtensionName)).AsNullIfWhiteSpace()
                    ?? this.SassExtension;

                this.ScssExtension =
                    ((string)element.Element(ScssExtensionName)).AsNullIfWhiteSpace()
                    ?? ((string)element.Attribute(ScssExtensionName)).AsNullIfWhiteSpace()
                    ?? this.ScssExtension;
            }
        }
Ejemplo n.º 6
0
        /// <summary>This will call any of the registered preprocessor plugins, that are named in the provided preprocessing config, in the order they are configured.
        /// It will only call the preprocessor if it reports it can handle the filetype. (Using Canprocess).
        /// It will loop through all of them and then return the processed file.
        /// A null value returned by the preprocessors indicates an exceptipon has occurred, and we should break of processing.
        /// The plugins themselves will report the detailed error through the logError and logExtendedError actions.</summary>
        /// <param name="contentItem">The content Item.</param>
        /// <param name="preprocessConfig">The preprocessing config.</param>
        /// <param name="minimalOutput"></param>
        /// <returns>If no preprocessors are found, the passed in file contents.
        /// Or the result of the pre processors, or null if there was an error while calling the preprocessors.</returns>
        internal ContentItem Process(ContentItem contentItem, PreprocessingConfig preprocessConfig, bool minimalOutput = false)
        {
            // Select all the registered preprocessors that are named in the configguration in the order in which they appear in the config and are valid for this file type.
            this.context.Log.Information("Registered preprocessors to use: {0}".InvariantFormat(string.Join(";", preprocessConfig.PreprocessingEngines)));
            var preprocessorsToUse = this.GetProcessors(contentItem, preprocessConfig);

            if (!preprocessorsToUse.Any())
            {
                return(contentItem);
            }

            this.context.SectionedAction(SectionIdParts.Preprocessing)
            .MakeCachable(contentItem, new { relativePath = Path.GetDirectoryName(contentItem.RelativeContentPath), preprocessConfig, pptu = preprocessorsToUse.Select(pptu => pptu.Name) })
            .RestoreFromCacheAction(cacheSection =>
            {
                contentItem = cacheSection.GetCachedContentItem(CacheFileCategories.PreprocessingResult);
                return(contentItem != null);
            })
            .Execute(cacheSection =>
            {
                // Loop through each available engine that was also configured
                // And check if the engine can process the file
                foreach (var preprocessingEngine in preprocessorsToUse)
                {
                    this.context.Log.Information("preprocessing with: {0}".InvariantFormat(preprocessingEngine.Name));

                    // Get the new content
                    contentItem = preprocessingEngine.Process(this.context, contentItem, preprocessConfig, minimalOutput);

                    if (contentItem == null)
                    {
                        return(false);
                    }
                }

                cacheSection.AddResult(contentItem, CacheFileCategories.PreprocessingResult);
                return(true);
            });

            return(contentItem);
        }
Ejemplo n.º 7
0
        /// <summary>The append file.</summary>
        /// <param name="writer">The writer.</param>
        /// <param name="filePath">The file path</param>
        /// <param name="sourceDirectory">The source directory</param>
        /// <param name="preprocessingConfig">The configuration for the preprocessing.</param>
        private void Append(TextWriter writer, string filePath, string sourceDirectory, PreprocessingConfig preprocessingConfig = null)
        {
            // Add a newline to make sure what comes next doesn't get mistakenly attached to the end of
            // a single-line comment or anything. add two so we get an easy-to-read separation between files
            // for debugging purposes.
            writer.WriteLine();
            writer.WriteLine();

            // if we want to separate files with semicolons and the previous file didn't have one, add one now
            if (this.AddSemicolons && !this.endedInSemicolon)
            {
                writer.Write(';');
            }

            string relativeFilePath =
                Path.IsPathRooted(filePath) && !sourceDirectory.IsNullOrWhitespace()
                ? filePath.MakeRelativeTo(sourceDirectory)
                : filePath;

            if (!this.MinimalOutput)
            {
                writer.WriteLine("/* {0} {1} */".InvariantFormat(relativeFilePath, filePath != relativeFilePath ? "(" + filePath + ")" : string.Empty));
                writer.WriteLine();
            }

            var contentItem = ContentItem.FromFile(filePath, relativeFilePath);

            // Executing any applicable preprocessors from the list of configured preprocessors on the file content
            if (preprocessingConfig != null && preprocessingConfig.Enabled)
            {
                contentItem = this.context.Preprocessing.Process(contentItem, preprocessingConfig, this.MinimalOutput);
                if (contentItem == null)
                {
                    throw new WorkflowException("Could not assembly the file {0} because one of the preprocessors threw an error.".InvariantFormat(filePath));
                }
            }

            // TODO:RTUIT: Use a writer/reader instead of getting the content and check differently for the endoign semicolon. Also fix not passing encoding. ONly when not using any preprocessors.
            var content = contentItem.Content;

            writer.Write(content);
            writer.WriteLine();

            // don't even bother checking for a semicolon if we aren't interested in adding one
            if (this.AddSemicolons)
            {
                this.endedInSemicolon = EndsWithSemicolon.IsMatch(content);
            }
        }
Ejemplo n.º 8
0
        /// <summary>Processed the contents of the file and returns the processed content.
        /// returns null if anything went wrong, and reports any errors through the lot delegates.</summary>
        /// <param name="context">The context.</param>
        /// <param name="contentItem">The content of the file.</param>
        /// <param name="preprocessingConfig">The pre processing configuration</param>
        /// <param name="minimalOutput">Is the goal to have the most minimal output (true skips lots of comments)</param>
        /// <returns>The processed contents or null of an error occurred.</returns>
        public ContentItem Process(IWebGreaseContext context, ContentItem contentItem, PreprocessingConfig preprocessingConfig, bool minimalOutput)
        {
            var settingsMinimalOutput = preprocessingConfig != null && preprocessingConfig.Element != null && (bool?)preprocessingConfig.Element.Attribute("minimalOutput") == true;

            context.SectionedAction(SectionIdParts.Preprocessing, SectionIdParts.Process, "WgInclude")
            .MakeCachable(contentItem, new { minimalOutput })
            .Execute(wgincludeCacheImportsSection =>
            {
                var workingFolder = context.GetWorkingSourceDirectory(contentItem.RelativeContentPath);
                var content       = contentItem.Content;
                if (string.IsNullOrWhiteSpace(content))
                {
                    return(true);
                }

                content     = IncludeRegex.Replace(content, match => ReplaceInputs(match, workingFolder, wgincludeCacheImportsSection, minimalOutput || settingsMinimalOutput));
                contentItem = ContentItem.FromContent(content, contentItem);
                return(true);
            });

            return(contentItem);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Create a SassConfig from the configuration element in the preprocessingConfig
 /// </summary>
 /// <param name="preprocessConfig">The pre processing config</param>
 /// <returns>The Sass Config</returns>
 private static SassConfig GetConfig(PreprocessingConfig preprocessConfig)
 {
     return(new SassConfig(preprocessConfig));
 }
Ejemplo n.º 10
0
        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);
        }