Exemple #1
0
        public async static Task <bool> MakeBundle(BundleDocument document, string bundleFile, Func <string, bool, Task> updateBundle)
        {
            // filePath must end in ".targetExtension.bundle"
            string extension = Path.GetExtension(Path.GetFileNameWithoutExtension(document.FileName));

            if (string.IsNullOrEmpty(extension))
            {
                Logger.Log("Skipping bundle file " + document.FileName + " without extension.  Bundle files must end with the output extension, followed by '.bundle'.");
                return(false);
            }

            Dictionary <string, string> files = await WatchFiles(document, updateBundle, bundleFile);

            string combinedContent = await CombineFiles(files, extension, document, bundleFile);

            bool bundleChanged = !File.Exists(bundleFile) || await FileHelpers.ReadAllTextRetry(bundleFile) != combinedContent;

            if (bundleChanged)
            {
                if (!ProjectHelpers.CheckOutFileFromSourceControl(bundleFile))
                {
                    throw new Exception("There was a problem checking out the file: " + bundleFile);
                }

                await FileHelpers.WriteAllTextRetry(bundleFile, combinedContent);

                Logger.Log("Web Essentials: Updated bundle: " + Path.GetFileName(bundleFile));
            }

            ProjectHelpers.AddFileToProject(document.FileName, bundleFile);

            return(bundleChanged);
        }
        private async Task <CompilerResult> ProcessResult(Process process, string errorText, string sourceFileName, string targetFileName, string mapFileName)
        {
            string result  = "";
            bool   success = false;
            IEnumerable <CompilerError> errors = null;

            try
            {
                if (process.ExitCode == 0)
                {
                    if (!string.IsNullOrEmpty(targetFileName) && File.Exists(targetFileName))
                    {
                        result = await FileHelpers.ReadAllTextRetry(targetFileName);
                    }

                    success = true;
                }
                else
                {
                    errors = ParseErrors(errorText);
                }
            }
            catch (FileNotFoundException missingFileException)
            {
                Logger.Log(ServiceName + ": " + Path.GetFileName(targetFileName) + " compilation failed. " + missingFileException.Message);
            }

            if (success)
            {
                var renewedResult = await PostProcessResult(result, sourceFileName, targetFileName, mapFileName);

                if (!ReferenceEquals(result, renewedResult))
                {
                    await FileHelpers.WriteAllTextRetry(targetFileName, renewedResult);

                    result = renewedResult;
                }
            }

            var compilerResult = await CompilerResultFactory.GenerateResult(
                sourceFileName : sourceFileName,
                targetFileName : targetFileName,
                mapFileName : mapFileName,
                isSuccess : success,
                result : result,
                errors : errors
                ) as CompilerResult;

            if (!success)
            {
                var firstError = compilerResult.Errors.Where(e => e != null).Select(e => e.Message).FirstOrDefault();

                if (firstError != null)
                {
                    Logger.Log(ServiceName + ": " + Path.GetFileName(sourceFileName) + " compilation failed: " + firstError);
                }
            }

            return(compilerResult);
        }
        protected async override Task RtlVariantHandler(CompilerResult result)
        {
            if (!WESettings.Instance.Css.RtlCss || result.RtlTargetFileName == null)
            {
                return;
            }

            string value = PostProcessResult(result.RtlResult, result.RtlTargetFileName, result.RtlSourceFileName);

            // Write output file
            if (result.RtlTargetFileName != null && (MinifyInPlace || !File.Exists(result.RtlTargetFileName) ||
                                                     value != await FileHelpers.ReadAllTextRetry(result.RtlTargetFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlTargetFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlTargetFileName, value);

                ProjectHelpers.AddFileToProject(result.RtlSourceFileName, result.RtlTargetFileName);
            }

            // Write map file
            if (GenerateSourceMap && (!File.Exists(result.RtlMapFileName) ||
                                      result.RtlResultMap != await FileHelpers.ReadAllTextRetry(result.RtlMapFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlMapFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlMapFileName, result.RtlResultMap);

                ProjectHelpers.AddFileToProject(result.RtlTargetFileName, result.RtlMapFileName);
            }
        }
        // Don't try-catch this method: We need to "address" all the bugs,
        // which may occur as the (node.js-based) service implement changes.
        private async Task <CompilerResult> ProcessResult(CompilerResult result, bool onlyPreview, string sourceFileName, string targetFileName)
        {
            if (result == null)
            {
                Logger.Log(ServiceName + ": " + Path.GetFileName(sourceFileName) + " compilation failed: The service failed to respond to this request\n\t\t\tPossible cause: Syntax Error!");
                return(await CompilerResultFactory.GenerateResult(sourceFileName, targetFileName));
            }
            if (!result.IsSuccess)
            {
                var firstError = result.Errors.Where(e => e != null).Select(e => e.Message).FirstOrDefault();

                if (firstError != null)
                {
                    Logger.Log(firstError);
                }

                return(result);
            }

            string resultString = PostProcessResult(result.Result, result.TargetFileName, result.SourceFileName);

            if (!onlyPreview)
            {
                // Write output file
                if (result.TargetFileName != null && (MinifyInPlace || !File.Exists(result.TargetFileName) ||
                                                      resultString != await FileHelpers.ReadAllTextRetry(result.TargetFileName)))
                {
                    ProjectHelpers.CheckOutFileFromSourceControl(result.TargetFileName);
                    await FileHelpers.WriteAllTextRetry(result.TargetFileName, resultString);

                    if (!(this is ILintCompiler))
                    {
                        ProjectHelpers.AddFileToProject(result.SourceFileName, result.TargetFileName);
                    }
                }

                // Write map file
                if (GenerateSourceMap && (!File.Exists(result.MapFileName) ||
                                          result.ResultMap != await FileHelpers.ReadAllTextRetry(result.MapFileName)))
                {
                    ProjectHelpers.CheckOutFileFromSourceControl(result.MapFileName);
                    await FileHelpers.WriteAllTextRetry(result.MapFileName, result.ResultMap);

                    if (!(this is ILintCompiler))
                    {
                        ProjectHelpers.AddFileToProject(result.TargetFileName, result.MapFileName);
                    }
                }

                await RtlVariantHandler(result);
            }

            return(CompilerResult.UpdateResult(result, resultString));
        }
Exemple #5
0
        protected async Task <bool> ExecuteAsync(string extension)
        {
            await FileHelpers.WriteAllTextRetry(_file + extension, string.Empty);

            if (await ScriptIntellisenseListener.ProcessAsync(_file))
            {
                return(true);
            }

            File.Delete(_file + extension);
            Logger.ShowMessage("An error occurred while processing " + Path.GetFileName(_file) + ".\nNo script file was generated.  For more details, see the output window.");

            return(false);
        }
Exemple #6
0
        public async static Task Write(IEnumerable <IntellisenseObject> objects, string file)
        {
            StringBuilder sb = new StringBuilder();

            if (Path.GetExtension(file).Equals(".ts", StringComparison.OrdinalIgnoreCase))
            {
                WriteTypeScript(objects, sb, file);
            }
            else
            {
                WriteJavaScript(objects, sb);
            }

            await FileHelpers.WriteAllTextRetry(file, sb.ToString());
        }
        private async static Threading.Task WriteBundleRecipe(string filePath, IEnumerable <ProjectItem> files, string output)
        {
            string            projectRoot = ProjectHelpers.GetProjectFolder(files.ElementAt(0).FileNames[1]);
            StringBuilder     sb          = new StringBuilder();
            XmlWriterSettings settings    = new XmlWriterSettings();

            settings.Indent = true;

            using (XmlWriter writer = XmlWriter.Create(sb, settings))
            {
                writer.WriteStartElement("bundle");
                writer.WriteAttributeString("minify", "true");
                writer.WriteAttributeString("runOnBuild", "true");
                writer.WriteAttributeString("output", output);
                writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
                writer.WriteAttributeString("xsi", "noNamespaceSchemaLocation", null, "http://vswebessentials.com/schemas/v1/bundle.xsd");
                writer.WriteComment("The order of the <file> elements determines the order of the file contents when bundled.");

                foreach (ProjectItem item in files)
                {
                    string relative = item.IsLink() ? item.FileNames[1] : "/" + FileHelpers.RelativePath(projectRoot, item.FileNames[1]);
                    writer.WriteElementString("file", relative);
                }

                writer.WriteEndElement();
            }

            sb.Replace(Encoding.Unicode.WebName, Encoding.UTF8.WebName);

            ProjectHelpers.CheckOutFileFromSourceControl(filePath);
            await FileHelpers.WriteAllTextRetry(filePath, sb.ToString());

            ProjectHelpers.AddFileToActiveProject(filePath, "None");

            _dte.ItemOperations.OpenFile(filePath);

            //TODO: Use XLINQ
            XmlDocument doc = await GetXmlDocument(filePath);

            if (doc == null)
            {
                return;
            }

            await Dispatcher.CurrentDispatcher.BeginInvoke(
                new Action(() => WriteBundleFile(filePath, doc).DoNotWait("writing " + filePath + "file")), DispatcherPriority.ApplicationIdle, null);
        }
Exemple #8
0
        private async Task <CompilerResult> ProcessResult(Process process, string errorText, string sourceFileName, string targetFileName, string mapFileName)
        {
            var result = await ValidateResult(process, targetFileName, errorText);

            var  resultText = result.Result;
            bool success    = result.IsSuccess;

            if (success)
            {
                var renewedResult = await PostProcessResult(resultText, sourceFileName, targetFileName, mapFileName);

                if (!ReferenceEquals(resultText, renewedResult))
                {
                    await FileHelpers.WriteAllTextRetry(targetFileName, renewedResult);

                    resultText = renewedResult;
                }
            }

            IEnumerable <CompilerError> errors = result.Errors;

            var compilerResult = await CompilerResultFactory.GenerateResult(
                sourceFileName : sourceFileName,
                targetFileName : targetFileName,
                mapFileName : mapFileName,
                isSuccess : success,
                result : resultText,
                errors : errors
                ) as CompilerResult;

            if (!success)
            {
                var firstError = compilerResult.Errors.Where(e => e != null).Select(e => e.Message).FirstOrDefault();

                if (firstError != null)
                {
                    Logger.Log(ServiceName + ": " + Path.GetFileName(sourceFileName) + " compilation failed: " + firstError);
                }
            }

            return(compilerResult);
        }
Exemple #9
0
        private async Task <string> UpdateSourceMapUrls(string content, string compiledFileName, string mapFileName)
        {
            if (!File.Exists(compiledFileName) || !File.Exists(mapFileName))
            {
                return(content);
            }

            var updatedFileContent = await GetUpdatedSourceMapFileContent(compiledFileName, mapFileName);

            if (updatedFileContent == null)
            {
                return(content);
            }

            await FileHelpers.WriteAllTextRetry(mapFileName, updatedFileContent);

            if (!GenerateSourceMap)
            {
                return(_sourceMapInCss.Replace(content, string.Empty));
            }

            return(UpdateSourceLinkInCssComment(content, FileHelpers.RelativePath(compiledFileName, mapFileName)));
        }
Exemple #10
0
        private async Task HandleRtlCss(CompilerResult result)
        {
            string value = result.RtlResult;

            // Write output file
            if (result.RtlTargetFileName != null && (MinifyInPlace || !File.Exists(result.RtlTargetFileName) ||
                                                     value != await FileHelpers.ReadAllTextRetry(result.RtlTargetFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlTargetFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlTargetFileName, value);

                ProjectHelpers.AddFileToProject(result.RtlSourceFileName, result.RtlTargetFileName);
            }

            // Write map file
            if (GenerateSourceMap && (!File.Exists(result.RtlMapFileName) ||
                                      result.RtlResultMap != await FileHelpers.ReadAllTextRetry(result.RtlMapFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlMapFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlMapFileName, result.RtlResultMap);

                ProjectHelpers.AddFileToProject(result.RtlTargetFileName, result.RtlMapFileName);
            }
        }
        private async static Threading.Task WriteBundleFile(string bundleFilePath, XmlDocument doc)
        {
            XmlNode bundleNode = doc.SelectSingleNode("//bundle");

            if (bundleNode == null)
            {
                return;
            }

            XmlNode outputAttr = bundleNode.Attributes["output"];

            if (outputAttr != null && (outputAttr.InnerText.Contains("/") || outputAttr.InnerText.Contains("\\")))
            {
                Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "The 'output' attribute should contain a file name without a path; '{0}' is not valid", outputAttr.InnerText));
                return;
            }

            Dictionary <string, string> files = new Dictionary <string, string>();

            // filePath must end in ".targetExtension.bundle"
            string extension = Path.GetExtension(Path.GetFileNameWithoutExtension(bundleFilePath));

            if (string.IsNullOrEmpty(extension))
            {
                Logger.Log("Skipping bundle file " + bundleFilePath + " without extension.  Bundle files must end with the output extension, followed by '.bundle'.");
                return;
            }

            XmlNodeList nodes = doc.SelectNodes("//file");

            foreach (XmlNode node in nodes)
            {
                string absolute;

                if (node.InnerText.Contains(":\\"))
                {
                    absolute = node.InnerText;
                }
                else
                {
                    absolute = ProjectHelpers.ToAbsoluteFilePath(node.InnerText, bundleFilePath);
                }

                if (File.Exists(absolute))
                {
                    if (!files.ContainsKey(absolute))
                    {
                        files.Add(absolute, node.InnerText);
                    }
                }
                else
                {
                    _dte.ItemOperations.OpenFile(bundleFilePath);
                    Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "Bundle error: The file '{0}' doesn't exist", node.InnerText));

                    return;
                }
            }

            string bundleSourcePath = outputAttr != null?Path.Combine(Path.GetDirectoryName(bundleFilePath), outputAttr.InnerText) : bundleFilePath.Replace(_ext, string.Empty);

            StringBuilder sb = new StringBuilder();

            foreach (string file in files.Keys)
            {
                //if (extension.Equals(".css", StringComparison.OrdinalIgnoreCase))
                //{
                //    sb.AppendLine("/*#source " + files[file] + " */");
                //}
                if (extension.Equals(".js", StringComparison.OrdinalIgnoreCase) && WESettings.Instance.JavaScript.GenerateSourceMaps)
                {
                    sb.AppendLine("///#source 1 1 " + files[file]);
                }

                if (!File.Exists(file))
                {
                    continue;
                }

                await new BundleFileWatcher().AttachFileObserverEvent(file);

                var source = await FileHelpers.ReadAllTextRetry(file);

                if (extension.Equals(".css", StringComparison.OrdinalIgnoreCase))
                {
                    // If the bundle is in the same folder as the CSS,
                    // or if does not have URLs, no need to normalize.
                    if (Path.GetDirectoryName(file) != Path.GetDirectoryName(bundleSourcePath) &&
                        source.IndexOf("url(", StringComparison.OrdinalIgnoreCase) > 0 &&
                        WESettings.Instance.Css.AdjustRelativePaths)
                    {
                        source = CssUrlNormalizer.NormalizeUrls(
                            tree: new CssParser().Parse(source, true),
                            targetFile: bundleSourcePath,
                            oldBasePath: file
                            );
                    }
                }

                sb.AppendLine(source);
            }

            bool bundleChanged = !File.Exists(bundleSourcePath) || await FileHelpers.ReadAllTextRetry(bundleSourcePath) != sb.ToString();

            if (bundleChanged)
            {
                ProjectHelpers.CheckOutFileFromSourceControl(bundleSourcePath);
                await FileHelpers.WriteAllTextRetry(bundleSourcePath, sb.ToString());

                Logger.Log("Web Essentials: Updated bundle: " + Path.GetFileName(bundleSourcePath));
            }

            ProjectHelpers.AddFileToProject(bundleFilePath, bundleSourcePath);

            if (bundleNode.Attributes["minify"] != null && bundleNode.Attributes["minify"].InnerText == "true")
            {
                await WriteMinFile(bundleSourcePath, extension, bundleChanged);
            }
        }