Example #1
0
 public ITest <GMMInput, GMMOutput> GetGMMTest()
 {
     if (container.TryGetExport(out ITest <GMMInput, GMMOutput> gmmTest))
     {
         return(gmmTest);
     }
     else
     {
         throw new InvalidOperationException("The specified module doesn't support the GMM objective.");
     }
 }
Example #2
0
        public void GetOrCreate_ValidActivatorAfterInitialization_Success()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                CompositionOperation operation = null;
                var value = new object();
                object GetOrCreateActivate(LifetimeContext getOrCreateContext, CompositionOperation getOrCreateOperator)
                {
                    Assert.Same(context, getOrCreateContext);
                    Assert.Same(operation, getOrCreateOperator);

                    return value;
                }
                object Activator(LifetimeContext activatorContext, CompositionOperation activatorOperation)
                {
                    operation = activatorOperation;
                    Assert.Same(value, context.GetOrCreate(1, operation, GetOrCreateActivate));
                    return "Hi";
                }

                Assert.Equal("Hi", CompositionOperation.Run(context, Activator));
                Assert.Same(value, context.GetOrCreate(1, operation, GetOrCreateActivate));
            }
        }
Example #3
0
 public void GetExport_MultipleReturns_ThrowsCompositionFailedException()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new MultiplePromises()))
     {
         Assert.Throws <CompositionFailedException>(() => host.TryGetExport(new CompositionContract(typeof(int)), out object export));
     }
 }
Example #4
0
 public void GetExport_FailedDependency_ThrowsCompositionFailedException()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new FailedDependency()))
     {
         Assert.Throws <CompositionFailedException>(() => host.TryGetExport(new CompositionContract(typeof(int)), out object export));
     }
 }
Example #5
0
 public void GetExport_AbstractMetadata_ThrowsInvalidOperationException()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
     {
         Assert.Throws <InvalidOperationException>(() => host.TryGetExport(typeof(Lazy <int, AbstractConstructor>), out object _));
     }
 }
Example #6
0
 public void TryGetExport_NullContract_ThrowsArgumentNullException()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
     {
         AssertExtensions.Throws <ArgumentNullException>("key", () => host.TryGetExport((CompositionContract)null, out object export));
     }
 }
Example #7
0
 public void GetExport_InvalidMetadata_ThrowsComposititionFailedException(Type type)
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
     {
         Assert.Throws <CompositionFailedException>(() => host.TryGetExport(type, out object _));
     }
 }
        public void Run_ValidContextAndAction_ReturnsExpected()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType <LifetimeContext>(export);

                var results = new List <string>();
                void NonPrequisiteAction1() => results.Add("NonPrequisiteAction1");
                void NonPrequisiteAction2() => results.Add("NonPrequisiteAction2");

                void PostCompositionAction1() => results.Add("PostCompositionAction1");
                void PostCompositionAction2() => results.Add("PostCompositionAction2");

                object Activator(LifetimeContext activatorContext, CompositionOperation activatorOperation)
                {
                    Assert.Same(context, activatorContext);

                    activatorOperation.AddNonPrerequisiteAction(NonPrequisiteAction1);
                    activatorOperation.AddNonPrerequisiteAction(NonPrequisiteAction2);

                    activatorOperation.AddPostCompositionAction(PostCompositionAction1);
                    activatorOperation.AddPostCompositionAction(PostCompositionAction2);

                    return("Hi");
                }

                Assert.Equal("Hi", CompositionOperation.Run(context, Activator));
                Assert.Equal(new string[] { "NonPrequisiteAction1", "NonPrequisiteAction2", "PostCompositionAction1", "PostCompositionAction2" }, results);
            }
        }
 public void GetExport_OpenGenericExportFactoryWithMetadata_ThrowsIndexOutOfRangeException()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost())
     {
         Assert.Throws <IndexOutOfRangeException>(() => host.TryGetExport(typeof(ExportFactory <,>), out object export));
     }
 }
Example #10
0
 public void GetExport_CompositionContextContract_ReturnsExpected()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
     {
         Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
         Assert.IsType <LifetimeContext>(export);
     }
 }
Example #11
0
 public void GetExport_MultipleDependencies_ReturnsExpected()
 {
     using (CompositionHost host = CompositionHost.CreateCompositionHost(new MultipleDependency()))
     {
         Assert.True(host.TryGetExport(new CompositionContract(typeof(int)), out object export));
         Assert.Equal("hi", export);
     }
 }
Example #12
0
        public void AddBoundInstance_NullInstance_ThrowsNullReferenceExceptionOnDisposal()
        {
            CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]);
            Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
            LifetimeContext context = Assert.IsType<LifetimeContext>(export);

            context.AddBoundInstance(null);
            Assert.Throws<NullReferenceException>(() => context.Dispose());
        }
Example #13
0
        public void FindContextWithin_NullSharingBoundary_ReturnsRoot()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                Assert.Same(context, context.FindContextWithin(null));
            }
        }
Example #14
0
        public void ToString_NoParent_ReturnsExpected()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                Assert.Equal("Root Lifetime Context", context.ToString());
            }
        }
Example #15
0
        public void FindContextWithin_UnknownSharingBoundary_ThrowsCompositionFailedException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                Assert.Throws<CompositionFailedException>(() => context.FindContextWithin("sharingBoundary"));
            }
        }
        public void Run_NullActivator_ThrowsArgumentNullException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType <LifetimeContext>(export);

                AssertExtensions.Throws <ArgumentNullException>("compositionRootActivator", () => CompositionOperation.Run(context, null));
            }
        }
Example #17
0
        public void GetOrCreate_NullOperation_ThrowsNullReferenceException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                Assert.Throws<NullReferenceException>(() => context.GetOrCreate(1, null, Activator));
            }
        }
Example #18
0
        public void GetExport_LazyOrExportFactoryContractType_ReturnsExpected(Type type, Type[] expectedContractTypes)
        {
            var tracker = new TrackingProvider();

            using (CompositionHost host = CompositionHost.CreateCompositionHost(tracker))
            {
                Assert.False(host.TryGetExport(type, out object export));
                Assert.Equal(expectedContractTypes, tracker.Contracts.Select(c => c.ContractType));
            }
        }
Example #19
0
        public void AddBoundInstance_Disposed_ThrowsObjectDisposedException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);
                context.Dispose();

                Assert.Throws<ObjectDisposedException>(() => context.AddBoundInstance(null));
            }
        }
Example #20
0
        public void GetExport_ExportFactoryContractWithMetadataConstraints_ReturnsExpected(Type contractType, string[] sharingBoundaryNames, Type[] expectedTypes)
        {
            var tracker = new TrackingProvider();

            using (CompositionHost host = CompositionHost.CreateCompositionHost(tracker))
            {
                var contract = new CompositionContract(contractType, "contractName", new Dictionary <string, object> {
                    { "SharingBoundaryNames", sharingBoundaryNames }
                });

                Assert.False(host.TryGetExport(contract, out object export));
                Assert.Equal(expectedTypes, tracker.Contracts.Select(c => c.ContractType));
            }
        }
Example #21
0
        public void GetExport_ImoportManyWithMetadataConstraints_ReturnsExpected(Type contractType, Type[] expectedTypes)
        {
            var tracker = new TrackingProvider();

            using (CompositionHost host = CompositionHost.CreateCompositionHost(tracker))
            {
                var contract = new CompositionContract(contractType, "contractName", new Dictionary <string, object> {
                    { "IsImportMany", true }
                });

                Assert.True(host.TryGetExport(contract, out object export));
                Assert.Empty(Assert.IsAssignableFrom <Array>(export));
                Assert.Equal(expectedTypes, tracker.Contracts.Select(c => c.ContractType));
            }
        }
Example #22
0
        public void GetOrCreate_NullActivator_ThrowsNullReferenceException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                object Activator(LifetimeContext activatorContext, CompositionOperation activatorOperation)
                {
                    Assert.Throws<NullReferenceException>(() => activatorContext.GetOrCreate(1, activatorOperation, null));
                    return "Hi";
                }

                Assert.Equal("Hi", CompositionOperation.Run(context, Activator));
            }
        }
        public void AddPostCompositionAction_NullAction_ThrowsArgumentNullException()
        {
            object Activator(LifetimeContext context, CompositionOperation operation)
            {
                AssertExtensions.Throws <ArgumentNullException>("action", () => operation.AddPostCompositionAction(null));
                return(null);
            }

            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType <LifetimeContext>(export);

                CompositionOperation.Run(context, Activator);
            }
        }
Example #24
0
        public void AddBoundInstance_NonNullInstance_DisposesInstanceOnDisposal()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                var instance = new DisposableInstance();
                context.AddBoundInstance(instance);
                Assert.Equal(0, instance.CalledDisposed);

                context.Dispose();
                Assert.Equal(1, instance.CalledDisposed);

                context.Dispose();
                Assert.Equal(1, instance.CalledDisposed);
            }
        }
Example #25
0
        public object GetService(Type serviceType, string key)
        {
            var typeInfo = serviceType?.GetTypeInfo() ?? throw new ArgumentNullException(nameof(serviceType));

            if (typeInfo.IsArray)
            {
                serviceType = typeInfo.GetElementType();

                var services = host.GetExports(serviceType, key).ToArray();
                var array    = Array.CreateInstance(serviceType, services.Length);

                services.CopyTo(array, 0);

                return(array);
            }

            if (typeInfo.IsGenericType && IEnumerableOfT.IsAssignableFrom(typeInfo.GetGenericTypeDefinition()))
            {
                serviceType = typeInfo.GenericTypeArguments[0];
                return(getServices.GetOrAdd(serviceType, t => (Func <string, object>)GetTypedServicesOfT.MakeGenericMethod(t).CreateDelegate(typeof(Func <string, object>), this))(key));
            }

            return(host.TryGetExport(serviceType, key, out var service) ? service : null);
        }
Example #26
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 = CompositionUtility.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}");

            _postProcessorsManager.IncrementalInitialize(_intermediateFolder, _currentBuildInfo, _lastBuildInfo, parameters[0].ForcePostProcess);

            var  manifests         = new List <Manifest>();
            bool transformDocument = false;

            foreach (var parameter in parameters)
            {
                if (parameter.CustomLinkResolver != null)
                {
                    ICustomHrefGenerator chg;
                    if (_container.TryGetExport(parameter.CustomLinkResolver, out chg))
                    {
                        parameter.ApplyTemplateSettings.HrefGenerator = chg;
                    }
                    else
                    {
                        Logger.LogWarning($"Custom href generator({parameter.CustomLinkResolver}) is not found.");
                    }
                }
                EnvironmentContext.FileAbstractLayerImpl =
                    FileAbstractLayerBuilder.Default
                    .ReadFromRealFileSystem(EnvironmentContext.BaseDirectory)
                    .WriteToRealFileSystem(parameter.OutputBaseDir)
                    .Create();
                if (parameter.Files.Count == 0)
                {
                    Logger.LogWarning(string.IsNullOrEmpty(parameter.VersionName)
                        ? "No files found, nothing is generated in default version."
                        : $"No files found, nothing is generated in version \"{parameter.VersionName}\".");
                    manifests.Add(new Manifest());
                    continue;
                }
                if (parameter.ApplyTemplateSettings.TransformDocument)
                {
                    transformDocument = true;
                }
                parameter.Metadata = _postProcessorsManager.PrepareMetadata(parameter.Metadata);
                if (!string.IsNullOrEmpty(parameter.VersionName))
                {
                    Logger.LogInfo($"Start building for version: {parameter.VersionName}");
                }
                manifests.Add(BuildCore(parameter, markdownServiceProvider));
            }

            EnvironmentContext.FileAbstractLayerImpl =
                FileAbstractLayerBuilder.Default
                .ReadFromRealFileSystem(parameters[0].OutputBaseDir)
                .WriteToRealFileSystem(parameters[0].OutputBaseDir)
                .Create();
            var generatedManifest = ManifestUtility.MergeManifest(manifests);

            ManifestUtility.RemoveDuplicateOutputFiles(generatedManifest.Files);
            using (new PerformanceScope("Process"))
            {
                _postProcessorsManager.Process(generatedManifest, outputDirectory);
            }

            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)
                {
                    _currentBuildInfo.Save(_intermediateFolder);
                    if (_lastBuildInfo != null)
                    {
                        Directory.Delete(Path.Combine(Environment.ExpandEnvironmentVariables(_intermediateFolder), _lastBuildInfo.DirectoryName), true);
                    }
                }
            }
        }
Example #27
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);
            }
        }
Example #28
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);

            try
            {
                _postProcessorsManager.IncrementalInitialize(_intermediateFolder, _currentBuildInfo, _lastBuildInfo, parameters[0].ForcePostProcess, parameters[0].MaxParallelism);

                var  manifests         = new List <Manifest>();
                bool transformDocument = false;
                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.");
                        }
                    }
                    if (_intermediateFolder == null)
                    {
                        EnvironmentContext.FileAbstractLayerImpl =
                            FileAbstractLayerBuilder.Default
                            .ReadFromRealFileSystem(EnvironmentContext.BaseDirectory)
                            .WriteToRealFileSystem(parameter.OutputBaseDir)
                            .Create();
                    }
                    else
                    {
                        EnvironmentContext.FileAbstractLayerImpl =
                            FileAbstractLayerBuilder.Default
                            .ReadFromRealFileSystem(EnvironmentContext.BaseDirectory)
                            .WriteToLink(Path.Combine(_intermediateFolder, _currentBuildInfo.DirectoryName))
                            .Create();
                    }
                    if (parameter.ApplyTemplateSettings.TransformDocument)
                    {
                        transformDocument = true;
                    }
                    if (parameter.Files.Count == 0)
                    {
                        Logger.LogWarning(string.IsNullOrEmpty(parameter.VersionName)
                            ? "No files found, nothing is generated in default version."
                            : $"No files found, nothing is generated in version \"{parameter.VersionName}\".");
                        manifests.Add(new Manifest());
                        continue;
                    }
                    parameter.Metadata = _postProcessorsManager.PrepareMetadata(parameter.Metadata);
                    if (!string.IsNullOrEmpty(parameter.VersionName))
                    {
                        Logger.LogInfo($"Start building for version: {parameter.VersionName}");
                    }
                    manifests.Add(BuildCore(parameter, markdownServiceProvider));
                }

                using (new LoggerPhaseScope("Postprocess", LogLevel.Verbose))
                {
                    var generatedManifest = ManifestUtility.MergeManifest(manifests);
                    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.Save(_intermediateFolder);
                                if (_lastBuildInfo != null)
                                {
                                    ClearCacheWithNoThrow(_lastBuildInfo.DirectoryName, true);
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.LogWarning($"Error happened while saving cache. Message: {ex.Message}.");
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                if (_intermediateFolder != null)
                {
                    ClearCacheWithNoThrow(_currentBuildInfo.DirectoryName, true);
                }
                throw;
            }
            finally
            {
                Logger.UnregisterListener(logCodesLogListener);
            }
        }