Beispiel #1
0
        public static async Tasks.Task CompileAsync(CompilerOptions options, Project project)
        {
            var tf = new JoinableTaskFactory(Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskContext);
            await tf.SwitchToMainThreadAsync();

            if (options == null || project == null || !LessCatalog.Catalog.TryGetValue(project.UniqueName, out ProjectMap map))
            {
                return;
            }

            IEnumerable <CompilerOptions> parents = map.LessFiles
                                                    .Where(l => l.Value.Exists(c => c == options))
                                                    .Select(l => l.Key)
                                                    .Union(new[] { options })
                                                    .Distinct();

            var sw = new Stopwatch();

            sw.Start();

            var compilerTaks = new List <Tasks.Task>();

            foreach (CompilerOptions parentOptions in parents.Where(p => p.Compile))
            {
                compilerTaks.Add(CompileSingleFileAsync(parentOptions));
            }

            await Tasks.Task.WhenAll(compilerTaks);

            sw.Stop();

            VsHelpers.WriteStatus($"LESS file compiled in {Math.Round(sw.Elapsed.TotalSeconds, 2)} seconds");
        }
Beispiel #2
0
        private static async Tasks.Task <bool> CompileSingleFileAsync(CompilerOptions options)
        {
            try
            {
                VsHelpers.CheckFileOutOfSourceControl(options.OutputFilePath);

                if (options.SourceMap)
                {
                    VsHelpers.CheckFileOutOfSourceControl(options.OutputFilePath + ".map");
                }

                CompilerResult result = await NodeProcess.ExecuteProcess(options);

                Logger.Log($"{result.Arguments}");

                if (result.HasError)
                {
                    Logger.Log(result.Error);
                    VsHelpers.WriteStatus($"Error compiling LESS file. See Output Window for details");
                }
                else
                {
                    AddFilesToProject(options);
                    Minify(options);
                }

                return(true);
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
                VsHelpers.WriteStatus($"Error compiling LESS file. See Output Window for details");
                return(false);
            }
        }
Beispiel #3
0
        public static void Minify(CompilerOptions options)
        {
            if (!options.Minify || !File.Exists(options.OutputFilePath))
            {
                return;
            }

            string cssContent = File.ReadAllText(options.OutputFilePath);

            var settings = new CssSettings
            {
                ColorNames  = CssColor.Strict,
                CommentMode = CssComment.Important
            };

            NUglify.UglifyResult result = Uglify.Css(cssContent, settings);

            if (result.HasErrors)
            {
                return;
            }

            string minFilePath = Path.ChangeExtension(options.OutputFilePath, ".min.css");

            VsHelpers.CheckFileOutOfSourceControl(minFilePath);
            File.WriteAllText(minFilePath, result.Code, new UTF8Encoding(true));
            VsHelpers.AddNestedFile(options.OutputFilePath, minFilePath);
        }
Beispiel #4
0
        private static void AddFilesToProject(CompilerOptions options)
        {
            Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();

            ProjectItem item = VsHelpers.DTE.Solution.FindProjectItem(options.InputFilePath);

            if (item?.ContainingProject != null)
            {
                if (options.OutputFilePath == Path.ChangeExtension(options.InputFilePath, ".css"))
                {
                    VsHelpers.AddNestedFile(options.InputFilePath, options.OutputFilePath);
                }
                else
                {
                    VsHelpers.AddFileToProject(item.ContainingProject, options.OutputFilePath);
                }

                string mapFilePath = Path.ChangeExtension(options.OutputFilePath, ".css.map");

                if (File.Exists(mapFilePath))
                {
                    VsHelpers.AddNestedFile(options.OutputFilePath, mapFilePath);
                }
            }
        }
Beispiel #5
0
        private async void DocumentSaved(object sender, TextDocumentFileActionEventArgs e)
        {
            if (e.FileActionType != FileActionTypes.ContentSavedToDisk || !_project.IsLessCompilationEnabled())
            {
                return;
            }

            if (NodeProcess.IsInstalling)
            {
                VsHelpers.WriteStatus("The LESS compiler is being installed. Please try again in a few seconds...");
            }
            else if (NodeProcess.IsReadyToExecute())
            {
                CompilerOptions options = await CompilerOptions.Parse(e.FilePath, _view.TextBuffer.CurrentSnapshot.GetText());

                if (_view.Properties.TryGetProperty(typeof(LessAdornment), out LessAdornment adornment))
                {
                    await adornment.Update(options);
                }

                if (options == null || !_project.SupportsCompilation() || !_project.IsLessCompilationEnabled())
                {
                    return;
                }

                await LessCatalog.UpdateFile(_project, options);

                if (await LessCatalog.EnsureCatalog(_project))
                {
                    await CompilerService.CompileAsync(options, _project);
                }
            }
        }
        public static async Task <CompilerOptions> Parse(string lessFilePath, string lessContent = null)
        {
            if (!File.Exists(lessFilePath) || ProjectMap.ShouldIgnore(lessFilePath))
            {
                return(null);
            }

            lessContent = lessContent ?? await VsHelpers.ReadFileAsync(lessFilePath);

            var options = new CompilerOptions(lessFilePath);

            // Compile
            if (Path.GetFileName(lessFilePath).StartsWith("_", StringComparison.Ordinal) ||
                lessContent.IndexOf("no-compile", StringComparison.OrdinalIgnoreCase) > -1)
            {
                options.Compile = false;
            }

            // Minify
            if (lessContent.IndexOf("no-minify", StringComparison.OrdinalIgnoreCase) > -1)
            {
                options.Minify = false;
            }

            // Arguments
            Match argsMatch = _regex.Match(lessContent, 0, Math.Min(500, lessContent.Length));

            if (argsMatch.Success)
            {
                string inFile = Path.GetFileName(options.InputFilePath);
                options.Arguments = $"\"{inFile}\" {argsMatch.Groups["args"].Value.TrimEnd('*', '/').Trim()}";
            }

            // Source map
            options.SourceMap = options.Arguments.IndexOf("--source-map", StringComparison.OrdinalIgnoreCase) > -1;

            // OutputFileName
            Match outMatch = _outFile.Match(options.Arguments);

            if (argsMatch.Success && outMatch.Success)
            {
                string relative = outMatch.Groups["out"].Value.Replace("/", "\\");
                options.OutputFilePath = Path.Combine(Path.GetDirectoryName(lessFilePath), relative);
            }
            else
            {
                options.OutputFilePath = Path.ChangeExtension(lessFilePath, ".css");

                if (argsMatch.Success)
                {
                    options.Arguments += $" \"{Path.GetFileName(options.OutputFilePath)}\"";
                }
            }

            // Trim the argument list
            options.Arguments = options.Arguments.Trim();

            return(options);
        }
Beispiel #7
0
        private async Task AddFile(string lessFilePath)
        {
            if (LessFiles.Keys.Any(c => c.InputFilePath == lessFilePath))
            {
                return;
            }

            string lessContent = await VsHelpers.ReadFileAsync(lessFilePath);

            CompilerOptions options = await CompilerOptions.Parse(lessFilePath, lessContent);

            LessFiles.Add(options, new List <CompilerOptions>());

            await AddOption(options, lessContent);
        }
Beispiel #8
0
        public static async Tasks.Task CompileProjectAsync(Project project)
        {
            if (project == null || !LessCatalog.Catalog.TryGetValue(project.UniqueName, out ProjectMap map))
            {
                return;
            }

            var compileTasks = new List <Tasks.Task>();

            foreach (CompilerOptions option in map.LessFiles.Keys)
            {
                if (option.Compile)
                {
                    compileTasks.Add(CompileSingleFile(option));
                }
            }

            await Tasks.Task.WhenAll(compileTasks);

            VsHelpers.WriteStatus($"LESS files in solution compiled");
        }
Beispiel #9
0
        private static void AddFilesToProject(CompilerOptions options)
        {
            ProjectItem item = VsHelpers.DTE.Solution.FindProjectItem(options.InputFilePath);

            if (item?.ContainingProject != null)
            {
                if (options.OutputFilePath == Path.ChangeExtension(options.InputFilePath, ".css"))
                {
                    VsHelpers.AddNestedFile(options.InputFilePath, options.OutputFilePath);
                }
                else
                {
                    VsHelpers.AddFileToProject(item.ContainingProject, options.OutputFilePath);
                }

                string mapFilePath = Path.ChangeExtension(options.OutputFilePath, ".css.map");

                if (File.Exists(mapFilePath))
                {
                    VsHelpers.AddNestedFile(options.OutputFilePath, mapFilePath);
                }
            }
        }
Beispiel #10
0
        public static async Tasks.Task CompileProjectAsync(Project project)
        {
            var tf = new JoinableTaskFactory(Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskContext);
            await tf.SwitchToMainThreadAsync();

            if (project == null || !LessCatalog.Catalog.TryGetValue(project.UniqueName, out ProjectMap map))
            {
                return;
            }

            var compileTasks = new List <Tasks.Task>();

            foreach (CompilerOptions option in map.LessFiles.Keys)
            {
                if (option.Compile)
                {
                    compileTasks.Add(CompileSingleFileAsync(option));
                }
            }

            await Tasks.Task.WhenAll(compileTasks);

            VsHelpers.WriteStatus($"LESS files in solution compiled");
        }