Exemplo n.º 1
0
 public DocumentBuilder(
     IEnumerable <Assembly> assemblies,
     ImmutableArray <string> postProcessorNames,
     string templateHash,
     string intermediateFolder = null,
     string commitFromSHA      = null,
     string commitToSHA        = null)
 {
     Logger.LogVerbose("Loading plug-in...");
     using (new LoggerPhaseScope("ImportPlugins", true))
     {
         var assemblyList = assemblies?.ToList();
         _container = GetContainer(assemblyList);
         _container.SatisfyImports(this);
         _currentBuildInfo.CommitFromSHA = commitFromSHA;
         _currentBuildInfo.CommitToSHA   = commitToSHA;
         if (intermediateFolder != null)
         {
             _currentBuildInfo.PluginHash    = ComputePluginHash(assemblyList);
             _currentBuildInfo.TemplateHash  = templateHash;
             _currentBuildInfo.DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder);
         }
     }
     Logger.LogInfo($"{Processors.Count()} plug-in(s) loaded.");
     foreach (var processor in Processors)
     {
         Logger.LogVerbose($"\t{processor.Name} with build steps ({string.Join(", ", from bs in processor.BuildSteps orderby bs.BuildOrder select bs.Name)})");
     }
     _postProcessors     = GetPostProcessor(postProcessorNames);
     _intermediateFolder = intermediateFolder;
     _lastBuildInfo      = LoadLastBuildInfo();
 }
Exemplo n.º 2
0
        public void TestIncrementalWithNullLastPostProcessInfo()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };

            // Pass null as last build info
            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, null, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content
            VerifyOutput(outputFolder, AppendStringPostProcessor.AppendString, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(9, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendStringPostProcessor.AppendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(false, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal("Cannot support incremental post processing, the reason is: last post processor info is null.", manifest.IncrementalInfo[0].Status.Details);
        }
Exemplo n.º 3
0
        public void TestIncrementalWithNotSupportIncrementalPostProcessor()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(NonIncrementalPostProcessor).Name
            });

            // Add not post processor which not support incremental
            var postProcessors = GetPostProcessors(typeof(NonIncrementalPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.False(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content should append nothing
            VerifyOutput(outputFolder, string.Empty, "a", "b", "c");

            // Check cached PostProcessInfo is null
            Assert.Null(currentBuildInfo.PostProcessInfo);

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(false, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal("Cannot support incremental post processing, the reason is: should not trace intermediate info.", manifest.IncrementalInfo[0].Status.Details);
        }
Exemplo n.º 4
0
 public DocumentBuilder(
     IEnumerable <Assembly> assemblies,
     ImmutableArray <string> postProcessorNames,
     string templateHash,
     string intermediateFolder = null,
     string commitFromSHA      = null,
     string commitToSHA        = null)
 {
     Logger.LogVerbose("Loading plug-in...");
     using (new LoggerPhaseScope("ImportPlugins", LogLevel.Verbose))
     {
         var assemblyList = assemblies?.ToList() ?? new List <Assembly>();
         assemblyList.Add(typeof(DocumentBuilder).Assembly);
         _container = CompositionUtility.GetContainer(assemblyList);
         _container.SatisfyImports(this);
         _currentBuildInfo.CommitFromSHA = commitFromSHA;
         _currentBuildInfo.CommitToSHA   = commitToSHA;
         if (intermediateFolder != null)
         {
             _currentBuildInfo.PluginHash    = ComputePluginHash(assemblyList);
             _currentBuildInfo.TemplateHash  = templateHash;
             _currentBuildInfo.DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder);
         }
     }
     Logger.LogInfo($"{Processors.Count()} plug-in(s) loaded.");
     foreach (var processor in Processors)
     {
         Logger.LogVerbose($"\t{processor.Name} with build steps ({string.Join(", ", from bs in processor.BuildSteps orderby bs.BuildOrder select bs.Name)})");
     }
     if (intermediateFolder != null)
     {
         var expanded = Environment.ExpandEnvironmentVariables(intermediateFolder);
         if (expanded.Length == 0)
         {
             expanded = ".";
         }
         _intermediateFolder = Path.GetFullPath(expanded);
     }
     _lastBuildInfo         = BuildInfo.Load(_intermediateFolder);
     _postProcessorsManager = new PostProcessorsManager(_container, postProcessorNames);
 }
Exemplo n.º 5
0
        public void Build(IList <DocumentBuildParameters> parameters, string outputDirectory)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            if (parameters.Count == 0)
            {
                throw new ArgumentException("Parameters are empty.", nameof(parameters));
            }

            var markdownServiceProvider = CompositionContainer.GetExport <IMarkdownServiceProvider>(_container, parameters[0].MarkdownEngineName);

            if (markdownServiceProvider == null)
            {
                Logger.LogError($"Unable to find markdown engine: {parameters[0].MarkdownEngineName}");
                throw new DocfxException($"Unable to find markdown engine: {parameters[0].MarkdownEngineName}");
            }
            Logger.LogInfo($"Markdown engine is {parameters[0].MarkdownEngineName}");

            var logCodesLogListener = new LogCodesLogListener();

            Logger.RegisterListener(logCodesLogListener);

            // Load schema driven processor from template
            var sdps = LoadSchemaDrivenDocumentProcessors(parameters[0]).ToList();

            if (sdps.Count > 0)
            {
                Logger.LogInfo($"{sdps.Count()} schema driven document processor plug-in(s) loaded.");
                Processors = Processors.Union(sdps);
            }

            BuildInfo lastBuildInfo    = null;
            var       currentBuildInfo =
                new BuildInfo
            {
                BuildStartTime = DateTime.UtcNow,
                DocfxVersion   = EnvironmentContext.Version,
            };

            try
            {
                lastBuildInfo = BuildInfo.Load(_intermediateFolder, true);

                currentBuildInfo.CommitFromSHA = _commitFromSHA;
                currentBuildInfo.CommitToSHA   = _commitToSHA;
                if (_intermediateFolder != null)
                {
                    currentBuildInfo.PluginHash   = ComputePluginHash(_assemblyList);
                    currentBuildInfo.TemplateHash = _templateHash;
                    if (!_cleanupCacheHistory && lastBuildInfo != null)
                    {
                        // Reuse the directory for last incremental if cleanup is disabled
                        currentBuildInfo.DirectoryName = lastBuildInfo.DirectoryName;
                    }
                    else
                    {
                        currentBuildInfo.DirectoryName = IncrementalUtility.CreateRandomDirectory(Environment.ExpandEnvironmentVariables(_intermediateFolder));
                    }
                }

                _postProcessorsManager.IncrementalInitialize(_intermediateFolder, currentBuildInfo, lastBuildInfo, parameters[0].ForcePostProcess, parameters[0].MaxParallelism);

                var  manifests         = new List <Manifest>();
                bool transformDocument = false;
                if (parameters.All(p => p.Files.Count == 0))
                {
                    Logger.LogWarning(
                        $"No file found, nothing will be generated. Please make sure docfx.json is correctly configured.",
                        code: WarningCodes.Build.EmptyInputFiles);
                }

                var noContentFound     = true;
                var emptyContentGroups = new List <string>();
                foreach (var parameter in parameters)
                {
                    if (parameter.CustomLinkResolver != null)
                    {
                        if (_container.TryGetExport(parameter.CustomLinkResolver, out ICustomHrefGenerator chg))
                        {
                            parameter.ApplyTemplateSettings.HrefGenerator = chg;
                        }
                        else
                        {
                            Logger.LogWarning($"Custom href generator({parameter.CustomLinkResolver}) is not found.");
                        }
                    }
                    FileAbstractLayerBuilder falBuilder;
                    if (_intermediateFolder == null)
                    {
                        falBuilder = FileAbstractLayerBuilder.Default
                                     .ReadFromRealFileSystem(EnvironmentContext.BaseDirectory)
                                     .WriteToRealFileSystem(parameter.OutputBaseDir);
                    }
                    else
                    {
                        falBuilder = FileAbstractLayerBuilder.Default
                                     .ReadFromRealFileSystem(EnvironmentContext.BaseDirectory)
                                     .WriteToLink(Path.Combine(_intermediateFolder, currentBuildInfo.DirectoryName));
                    }
                    if (!string.IsNullOrEmpty(parameter.FALName))
                    {
                        if (_container.TryGetExport <IInputFileAbstractLayerBuilderProvider>(
                                parameter.FALName, out var provider))
                        {
                            falBuilder = provider.Create(falBuilder, parameter);
                        }
                        else
                        {
                            Logger.LogWarning($"Input fal builder provider not found, name: {parameter.FALName}.");
                        }
                    }
                    EnvironmentContext.FileAbstractLayerImpl = falBuilder.Create();
                    if (parameter.ApplyTemplateSettings.TransformDocument)
                    {
                        transformDocument = true;
                    }

                    if (parameter.Files.Count == 0)
                    {
                        manifests.Add(new Manifest());
                    }
                    else
                    {
                        if (!parameter.Files.EnumerateFiles().Any(s => s.Type == DocumentType.Article))
                        {
                            if (!string.IsNullOrEmpty(parameter.GroupInfo?.Name))
                            {
                                emptyContentGroups.Add(parameter.GroupInfo.Name);
                            }
                        }
                        else
                        {
                            noContentFound = false;
                        }

                        parameter.Metadata = _postProcessorsManager.PrepareMetadata(parameter.Metadata);
                        if (!string.IsNullOrEmpty(parameter.VersionName))
                        {
                            Logger.LogInfo($"Start building for version: {parameter.VersionName}");
                        }

                        using (new LoggerPhaseScope("BuildCore"))
                        {
                            manifests.Add(BuildCore(parameter, markdownServiceProvider, currentBuildInfo, lastBuildInfo));
                        }
                    }
                }
                if (noContentFound)
                {
                    Logger.LogWarning(
                        $"No content file found. Please make sure the content section of docfx.json is correctly configured.",
                        code: WarningCodes.Build.EmptyInputContents);
                }
                else if (emptyContentGroups.Count > 0)
                {
                    Logger.LogWarning(
                        $"No content file found in group: {string.Join(",", emptyContentGroups)}. Please make sure the content section of docfx.json is correctly configured.",
                        code: WarningCodes.Build.EmptyInputContents);
                }

                using (new LoggerPhaseScope("Postprocess", LogLevel.Verbose))
                {
                    var generatedManifest = ManifestUtility.MergeManifest(manifests);
                    generatedManifest.SitemapOptions = parameters.FirstOrDefault()?.SitemapOptions;
                    ManifestUtility.RemoveDuplicateOutputFiles(generatedManifest.Files);
                    ManifestUtility.ApplyLogCodes(generatedManifest.Files, logCodesLogListener.Codes);

                    EnvironmentContext.FileAbstractLayerImpl =
                        FileAbstractLayerBuilder.Default
                        .ReadFromManifest(generatedManifest, parameters[0].OutputBaseDir)
                        .WriteToManifest(generatedManifest, parameters[0].OutputBaseDir)
                        .Create();
                    using (new PerformanceScope("Process"))
                    {
                        _postProcessorsManager.Process(generatedManifest, outputDirectory);
                    }

                    using (new PerformanceScope("Dereference"))
                    {
                        if (parameters[0].KeepFileLink)
                        {
                            var count = (from f in generatedManifest.Files
                                         from o in f.OutputFiles
                                         select o.Value into v
                                         where v.LinkToPath != null
                                         select v).Count();
                            if (count > 0)
                            {
                                Logger.LogInfo($"Skip dereferencing {count} files.");
                            }
                        }
                        else
                        {
                            generatedManifest.Dereference(parameters[0].OutputBaseDir, parameters[0].MaxParallelism);
                        }
                    }

                    using (new PerformanceScope("SaveManifest"))
                    {
                        // Save to manifest.json
                        EnvironmentContext.FileAbstractLayerImpl =
                            FileAbstractLayerBuilder.Default
                            .ReadFromRealFileSystem(parameters[0].OutputBaseDir)
                            .WriteToRealFileSystem(parameters[0].OutputBaseDir)
                            .Create();
                        SaveManifest(generatedManifest);
                    }

                    using (new PerformanceScope("Cleanup"))
                    {
                        EnvironmentContext.FileAbstractLayerImpl = null;

                        // overwrite intermediate cache files
                        if (_intermediateFolder != null && transformDocument)
                        {
                            try
                            {
                                currentBuildInfo.IsValid = Logger.WarningCount < Logger.WarningThrottling;
                                currentBuildInfo.Save(_intermediateFolder);
                                if (_cleanupCacheHistory)
                                {
                                    ClearCacheExcept(currentBuildInfo.DirectoryName);
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.LogWarning($"Error happened while saving cache. Message: {ex.Message}.");
                            }
                        }
                    }
                }
            }
            catch
            {
                // Leave cache folder there as it contains historical data
                // exceptions happens in this build does not corrupt the cache theoretically
                // however the cache file created by this build will never be cleaned up with DisableIncrementalFolderCleanup option
                if (_intermediateFolder != null && _cleanupCacheHistory)
                {
                    ClearCacheExcept(lastBuildInfo?.DirectoryName);
                }
                throw;
            }
            finally
            {
                Logger.UnregisterListener(logCodesLogListener);
            }
        }
Exemplo n.º 6
0
        public void TestIncrementalWithContextChange()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendIntegerPostProcessor).Name
            });

            // Add post processor which has changed context hash
            var postProcessors = GetPostProcessors(typeof(AppendIntegerPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content
            VerifyOutput(outputFolder, AppendIntegerPostProcessor.AppendInteger, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendIntegerPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.NotNull(postProcessorInfos[0].IncrementalContextHash);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(6, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendIntegerPostProcessor.AppendInteger, null, "a", "b", "c");

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(false, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal(@"Cannot support incremental post processing, the reason is: post processor info changed from last {""Name"":""AppendIntegerPostProcessor""} to current {""Name"":""AppendIntegerPostProcessor"",""IncrementalContextHash"":""1024""}.",
                         manifest.IncrementalInfo[0].Status.Details);
        }
Exemplo n.º 7
0
        public void TestIncrementalWithFileInDirectory()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendStringPostProcessor).Name
            });

            // Exclude c, which is not incremental
            var preparedManifest = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental_with_directory.json");

            PrepareCachedOutput(intermediateFolder, lastBuildInfo, AppendStringPostProcessor.AppendString, preparedManifest.Files, AppendStringPostProcessor.AdditionalExtensionString, "a/b");

            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.True(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental_with_directory.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a/b", "c");
            CreateFile("breadcrumb.json", "breadcrumb", outputFolder);
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.Equal(3, manifest.Files.Count);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a/b.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "breadcrumb.json").IsIncremental);

            // Check output content
            VerifyOutput(outputFolder, AppendStringPostProcessor.AppendString, "a/b", "c");
            Assert.Equal("breadcrumb", EnvironmentContext.FileAbstractLayer.ReadAllText(Path.Combine(outputFolder, "breadcrumb.json")));

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(6, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendStringPostProcessor.AppendString, AppendStringPostProcessor.AdditionalExtensionString, "a/b", "c");
        }
Exemplo n.º 8
0
        public void TestIncrementalWithFirstCanIncrementalButSecondShouldnotTraceIncrementalInfo()
        {
            //        | Should trace incremental info | Can incremental |
            // ---------------------------------------------------------
            // First  |               yes             |       yes       |
            // Second |               no              |       no        |

            // Step 1: trace intermediate info and post process incrementally
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendStringPostProcessor).Name
            });

            // Exclude c, which is not incremental
            var preparedManifest = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");

            PrepareCachedOutput(intermediateFolder, lastBuildInfo, AppendStringPostProcessor.AppendString, preparedManifest.Files, AppendStringPostProcessor.AdditionalExtensionString, "a", "b");

            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var appendString   = $"{AppendStringPostProcessor.AppendString}";
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.True(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.Equal(3, manifest.Files.Count);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a.md").IsIncremental);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "b.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
            foreach (var file in manifest.Files)
            {
                Assert.True(file.OutputFiles.ContainsKey(AppendStringPostProcessor.AdditionalExtensionString));
            }

            // Check output content
            VerifyOutput(outputFolder, appendString, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(9, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, appendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

            // Step 2: should not trace inter incremental post process
            currentBuildInfo = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            lastBuildInfo = new BuildInfo
            {
                DirectoryName   = Path.GetFileName(increContext.CurrentBaseDir),
                PostProcessInfo = increContext.CurrentInfo
            };

            // Add post processor which not supports incremental
            postProcessors.AddRange(GetPostProcessors(typeof(NonIncrementalPostProcessor)));
            increContext = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.False(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            outputFolder = GetRandomFolder();
            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content
            VerifyOutput(outputFolder, appendString, "a", "b", "c");

            // Check cached PostProcessInfo should be null
            Assert.Null(currentBuildInfo.PostProcessInfo);
        }
Exemplo n.º 9
0
        public void TestIncrementalBasicScenario()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendStringPostProcessor).Name
            });

            // Exclude c, which is not incremental
            var preparedManifest = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");

            PrepareCachedOutput(intermediateFolder, lastBuildInfo, AppendStringPostProcessor.AppendString, preparedManifest.Files, AppendStringPostProcessor.AdditionalExtensionString, "a", "b");

            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.True(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.Equal(3, manifest.Files.Count);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a.md").IsIncremental);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "b.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
            foreach (var file in manifest.Files)
            {
                Assert.True(file.OutputFiles.ContainsKey(AppendStringPostProcessor.AdditionalExtensionString));
            }

            // Check output content
            VerifyOutput(outputFolder, AppendStringPostProcessor.AppendString, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(9, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendStringPostProcessor.AppendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(true, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal("Can support incremental post processing.", manifest.IncrementalInfo[0].Status.Details);
        }
Exemplo n.º 10
0
        public void TestIncrementalWithFirstCannotIncrementalButSecondCanIncremental()
        {
            //        | Should trace incremental info | Can incremental |
            // ---------------------------------------------------------
            // First  |               yes             |       no        |
            // Second |               yes             |       yes       |

            var          intermediateFolder = GetRandomFolder();
            const string phaseName          = PrependIncrementalPhaseName + "FirstCannotIncrementalButSecondCanIncremental";
            var          postProcessors     = GetPostProcessors(typeof(AppendStringPostProcessor), typeof(AppendIntegerPostProcessor));
            var          appendString       = $"{AppendStringPostProcessor.AppendString}{AppendIntegerPostProcessor.AppendInteger}";
            IncrementalPostProcessorsContext increContext = null;

            IncrementalActions
                (phaseName, () =>
            {
                // Step 1: trace intermediate info
                using (new LoggerPhaseScope(phaseName + "First"))
                {
                    var currentBuildInfo = new BuildInfo
                    {
                        DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
                    };
                    increContext = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, null, postProcessors, true);

                    // Check context
                    Assert.True(increContext.ShouldTraceIncrementalInfo);
                    Assert.False(increContext.IsIncremental);

                    var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
                    var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
                    var outputFolder = GetRandomFolder();
                    PrepareOutput(outputFolder, "a", "b", "c");
                    increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

                    // Check incremental flag
                    Assert.True(manifest.Files.All(f => f.IsIncremental == false));

                    // Check output content
                    VerifyOutput(outputFolder, appendString, "a", "b", "c");

                    // Check cached PostProcessInfo
                    Assert.NotNull(currentBuildInfo.PostProcessInfo);

                    var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;
                    Assert.Equal(2, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
                    Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
                    Assert.Null(postProcessorInfos[0].IncrementalContextHash);
                    Assert.Equal($"{typeof(AppendIntegerPostProcessor).Name}", postProcessorInfos[1].Name);
                    Assert.Equal(AppendIntegerPostProcessor.HashValue, postProcessorInfos[1].IncrementalContextHash);
                    Assert.NotNull(postProcessorInfos[1].ContextInfoFile);
                    Assert.Equal(new List <string> {
                        "a.html", "b.html", "c.html"
                    },
                                 JsonUtility.Deserialize <List <string> >(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName, postProcessorInfos[1].ContextInfoFile)));

                    Assert.Equal(3, currentBuildInfo.PostProcessInfo.ManifestItems.Count);
                    Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

                    var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;
                    Assert.Equal(9, postProcessOutputs.Count);
                    VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, appendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

                    // Check log messages
                    var logs = Listener.Items.Where(i => i.Phase.StartsWith(phaseName)).ToList();
                    Assert.Equal(3, logs.Count);
                    Assert.True(logs.All(l => l.Message.Contains("is not in html format.")));
                }
            }, () =>
            {
                // Step 2: incremental post process
                using (new LoggerPhaseScope(phaseName + "Second"))
                {
                    var secondBuildInfo = new BuildInfo
                    {
                        DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
                    };
                    var lastBuildInfo = new BuildInfo
                    {
                        DirectoryName   = Path.GetFileName(increContext.CurrentBaseDir),
                        PostProcessInfo = increContext.CurrentInfo
                    };
                    increContext = new IncrementalPostProcessorsContext(intermediateFolder, secondBuildInfo, lastBuildInfo, postProcessors, true);

                    // Check context
                    Assert.True(increContext.ShouldTraceIncrementalInfo);
                    Assert.True(increContext.IsIncremental);

                    var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
                    var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
                    var outputFolder = GetRandomFolder();
                    PrepareOutput(outputFolder, "a", "b", "c");
                    increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

                    // Check incremental flag
                    Assert.Equal(3, manifest.Files.Count);
                    Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a.md").IsIncremental);
                    Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "b.md").IsIncremental);
                    Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
                    foreach (var file in manifest.Files)
                    {
                        Assert.True(file.OutputFiles.ContainsKey(AppendStringPostProcessor.AdditionalExtensionString));
                    }

                    // Check output content
                    VerifyOutput(outputFolder, appendString, "a", "b", "c");

                    // Check cached PostProcessInfo
                    Assert.NotNull(secondBuildInfo.PostProcessInfo);

                    var postProcessorInfos = secondBuildInfo.PostProcessInfo.PostProcessorInfos;
                    Assert.Equal(2, secondBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
                    Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
                    Assert.Null(postProcessorInfos[0].IncrementalContextHash);
                    Assert.Equal($"{typeof(AppendIntegerPostProcessor).Name}", postProcessorInfos[1].Name);
                    Assert.Equal(AppendIntegerPostProcessor.HashValue, postProcessorInfos[1].IncrementalContextHash);
                    Assert.NotNull(postProcessorInfos[1].ContextInfoFile);
                    Assert.Equal(new List <string> {
                        "a.html", "b.html", "c.html"
                    },
                                 JsonUtility.Deserialize <List <string> >(Path.Combine(intermediateFolder, secondBuildInfo.DirectoryName, postProcessorInfos[1].ContextInfoFile)));

                    Assert.Equal(3, secondBuildInfo.PostProcessInfo.ManifestItems.Count);
                    Assert.Equal <ManifestItem>(manifest.Files, secondBuildInfo.PostProcessInfo.ManifestItems);

                    var postProcessOutputs = secondBuildInfo.PostProcessInfo.PostProcessOutputs;
                    Assert.Equal(9, postProcessOutputs.Count);
                    VerifyCachedOutput(Path.Combine(intermediateFolder, secondBuildInfo.DirectoryName), postProcessOutputs, appendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

                    // Check log messages
                    var logs = Listener.Items.Where(i => i.Phase.StartsWith(phaseName)).ToList();
                    Assert.Equal(3, logs.Count);
                    Assert.True(logs.All(l => l.Message.Contains("is not in html format.")));
                }
            });
        }