Exemple #1
0
        public void SaveIntermediateModel(IncrementalBuildContext incrementalContext)
        {
            if (!ShouldTraceIncrementalInfo)
            {
                return;
            }
            var processor = (ISupportIncrementalDocumentProcessor)Processor;
            var mi        = incrementalContext.GetModelLoadInfo(this);
            var lmm       = incrementalContext.GetLastIntermediateModelManifest(this);
            var cmm       = incrementalContext.GetCurrentIntermediateModelManifest(this);

            foreach (var pair in mi)
            {
                IncrementalUtility.RetryIO(() =>
                {
                    string fileName = IncrementalUtility.GetRandomEntry(incrementalContext.BaseDir);
                    if (pair.Value == null)
                    {
                        if (lmm == null)
                        {
                            throw new BuildCacheException($"Full build hasn't loaded model {pair.Key}");
                        }
                        string lfn;
                        if (!lmm.Models.TryGetValue(pair.Key, out lfn))
                        {
                            throw new BuildCacheException($"Last build hasn't loaded model {pair.Key}");
                        }
                        File.Move(Path.Combine(incrementalContext.LastBaseDir, lfn), Path.Combine(incrementalContext.BaseDir, fileName));
                    }
                    else
                    {
                        var key   = TypeForwardedToRelativePath.NormalizedWorkingFolder + pair.Key;
                        var model = Models.Find(m => m.Key == key);
                        using (var stream = File.Create(Path.Combine(incrementalContext.BaseDir, fileName)))
                        {
                            processor.SaveIntermediateModel(model, stream);
                        }
                    }
                    cmm.Models.Add(pair.Key, fileName);
                });
            }
        }
Exemple #2
0
        public IEnumerable <FileModel> LoadIntermediateModel(IncrementalBuildContext incrementalContext, string fileName)
        {
            if (!CanIncrementalBuild)
            {
                yield break;
            }
            var processor = (ISupportIncrementalDocumentProcessor)Processor;
            var cmm       = incrementalContext.GetCurrentIntermediateModelManifest(this);

            if (!cmm.Models.TryGetValue(fileName, out List <ModelManifestItem> cfn))
            {
                throw new BuildCacheException($"Last build hasn't loaded model {fileName}");
            }
            foreach (var item in cfn)
            {
                using var stream = File.OpenRead(
                          Path.Combine(Environment.ExpandEnvironmentVariables(incrementalContext.BaseDir), item.FilePath));
                yield return(processor.LoadIntermediateModel(stream));
            }
        }
Exemple #3
0
        internal static void RelayBuildMessage(IncrementalBuildContext context, IEnumerable <HostService> hostServices, BuildPhase phase)
        {
            var falseSet = new HashSet <string>(from h in hostServices
                                                where !h.CanIncrementalBuild
                                                from f in h.Models
                                                select f.OriginalFileAndType.File,
                                                FilePathComparer.OSPlatformSensitiveStringComparer);
            var fileSet = new HashSet <string>(from h in hostServices
                                               where h.CanIncrementalBuild
                                               from f in GetFilesToRelayMessages(context, h)
                                               where !falseSet.Contains(f)
                                               select f,
                                               FilePathComparer.OSPlatformSensitiveStringComparer);

            var lastBuildMessageInfo = GetPhaseMessageInfo(context.LastBuildVersionInfo?.BuildMessage, phase);

            foreach (var file in fileSet)
            {
                lastBuildMessageInfo.Replay(file);
            }
        }
 private void Prepare(
     DocumentBuildParameters parameters,
     DocumentBuildContext context,
     TemplateProcessor templateProcessor,
     string markdownServiceContextHash,
     out IHostServiceCreator hostServiceCreator,
     out PhaseProcessor phaseProcessor)
 {
     if (IntermediateFolder != null && parameters.ApplyTemplateSettings.TransformDocument)
     {
         using (new LoggerPhaseScope("CreateIncrementalBuildContext", false))
             using (new PerformanceScope("CreateIncrementalBuildContext", LogLevel.Verbose))
             {
                 context.IncrementalBuildContext = IncrementalBuildContext.Create(parameters, CurrentBuildInfo, LastBuildInfo, IntermediateFolder, markdownServiceContextHash);
             }
         hostServiceCreator = new HostServiceCreatorWithIncremental(context);
         phaseProcessor     = new PhaseProcessor
         {
             Handlers =
             {
                 new CompilePhaseHandler(context).WithIncremental(),
                 new LinkPhaseHandler(context,                      templateProcessor).WithIncremental(),
             }
         };
     }
     else
     {
         hostServiceCreator = new HostServiceCreator(context);
         phaseProcessor     = new PhaseProcessor
         {
             Handlers =
             {
                 new CompilePhaseHandler(context),
                 new LinkPhaseHandler(context,    templateProcessor),
             }
         };
     }
 }
Exemple #5
0
        public void SaveIntermediateModel(IncrementalBuildContext incrementalContext)
        {
            if (!ShouldTraceIncrementalInfo)
            {
                return;
            }
            var processor = (ISupportIncrementalDocumentProcessor)Processor;
            var mi        = incrementalContext.GetModelLoadInfo(this);
            var lmm       = incrementalContext.GetLastIntermediateModelManifest(this);
            var cmm       = incrementalContext.GetCurrentIntermediateModelManifest(this);

            Parallel.ForEach(mi, new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            }, pair =>
            {
                IncrementalUtility.RetryIO(() =>
                {
                    var items = new List <ModelManifestItem>();
                    if (pair.Value == null)
                    {
                        if (lmm == null)
                        {
                            throw new BuildCacheException($"Full build hasn't loaded model {pair.Key}");
                        }
                        if (!lmm.Models.TryGetValue(pair.Key, out List <ModelManifestItem> lfn))
                        {
                            throw new BuildCacheException($"Last build hasn't loaded model {pair.Key}");
                        }

                        if (FilePathComparerWithEnvironmentVariable.OSPlatformSensitiveRelativePathComparer.Equals(
                                incrementalContext.BaseDir,
                                incrementalContext.LastBaseDir))
                        {
                            items.AddRange(lfn);
                        }
                        else
                        {
                            foreach (var item in lfn)
                            {
                                // use copy rather than move because if the build failed, the intermediate files of last successful build shouldn't be corrupted.
                                string fileName = IncrementalUtility.GetRandomEntry(incrementalContext.BaseDir);
                                File.Copy(
                                    Path.Combine(Environment.ExpandEnvironmentVariables(incrementalContext.LastBaseDir), item.FilePath),
                                    Path.Combine(Environment.ExpandEnvironmentVariables(incrementalContext.BaseDir), fileName));
                                items.Add(new ModelManifestItem()
                                {
                                    SourceFilePath = item.SourceFilePath, FilePath = fileName
                                });
                            }
                        }
                    }
                    else
                    {
                        var models = Models.Where(m => m.OriginalFileAndType.File == pair.Key).ToList();
                        foreach (var model in models)
                        {
                            string fileName = IncrementalUtility.GetRandomEntry(incrementalContext.BaseDir);
                            using (var stream = File.Create(
                                       Path.Combine(
                                           Environment.ExpandEnvironmentVariables(incrementalContext.BaseDir),
                                           fileName)))
                            {
                                processor.SaveIntermediateModel(model, stream);
                            }
                            items.Add(new ModelManifestItem()
                            {
                                SourceFilePath = model.FileAndType.File, FilePath = fileName
                            });
                        }
                    }
                    lock (cmm)
                    {
                        cmm.Models.Add(pair.Key, items);
                    }
                });
            });
        }
Exemple #6
0
        public void ReloadUnloadedModels(IncrementalBuildContext incrementalContext, BuildPhase loadedAt)
        {
            var mi = incrementalContext.GetModelLoadInfo(this);

            ReloadUnloadedModelsPerCondition(incrementalContext, loadedAt, f => mi[f] == null);
        }
Exemple #7
0
        private Manifest BuildCore(DocumentBuildParameters parameters)
        {
            using (new LoggerPhaseScope(PhaseName, true))
            {
                Logger.LogInfo($"Max parallelism is {parameters.MaxParallelism}.");
                Directory.CreateDirectory(parameters.OutputBaseDir);
                var context = new DocumentBuildContext(
                    Path.Combine(Directory.GetCurrentDirectory(), parameters.OutputBaseDir),
                    parameters.Files.EnumerateFiles(),
                    parameters.ExternalReferencePackages,
                    parameters.XRefMaps,
                    parameters.MaxParallelism,
                    parameters.Files.DefaultBaseDir);
                if (ShouldTraceIncrementalInfo)
                {
                    context.IncrementalBuildContext = IncrementalBuildContext.Create(parameters, CurrentBuildInfo, LastBuildInfo, IntermediateFolder);
                    Logger.RegisterListener(context.IncrementalBuildContext.CurrentBuildVersionInfo.BuildMessage.GetListener());
                    if (context.IncrementalBuildContext.CanVersionIncremental)
                    {
                        context.IncrementalBuildContext.LoadChanges();
                        Logger.LogVerbose($"Before expanding dependency before build, changes: {JsonUtility.Serialize(context.IncrementalBuildContext.ChangeDict, Formatting.Indented)}");
                        var dependencyGraph = context.IncrementalBuildContext.LastBuildVersionInfo.Dependency;
                        context.IncrementalBuildContext.ExpandDependency(dependencyGraph, d => dependencyGraph.DependencyTypes[d.Type].Phase == BuildPhase.Build || dependencyGraph.DependencyTypes[d.Type].TriggerBuild);
                        Logger.LogVerbose($"After expanding dependency before build, changes: {JsonUtility.Serialize(context.IncrementalBuildContext.ChangeDict, Formatting.Indented)}");
                    }
                }

                Logger.LogVerbose("Start building document...");

                // Start building document...
                List <HostService> hostServices = null;
                try
                {
                    using (var templateProcessor = parameters.TemplateManager?.GetTemplateProcessor(context, parameters.MaxParallelism) ?? TemplateProcessor.DefaultProcessor)
                    {
                        IMarkdownService markdownService;
                        using (new LoggerPhaseScope("CreateMarkdownService", true))
                        {
                            markdownService = CreateMarkdownService(parameters, templateProcessor.Tokens.ToImmutableDictionary());
                        }

                        using (new LoggerPhaseScope("Load", true))
                        {
                            hostServices = GetInnerContexts(parameters, Processors, templateProcessor, markdownService, context).ToList();
                        }

                        var manifest = BuildCore(hostServices, context, parameters.VersionName).ToList();

                        // Use manifest from now on
                        using (new LoggerPhaseScope("UpdateContext", true))
                        {
                            UpdateContext(context);
                        }

                        // Run getOptions from Template
                        using (new LoggerPhaseScope("FeedOptions", true))
                        {
                            FeedOptions(manifest, context);
                        }

                        // Template can feed back xref map, actually, the anchor # location can only be determined in template
                        using (new LoggerPhaseScope("FeedXRefMap", true))
                        {
                            FeedXRefMap(manifest, context);
                        }

                        using (new LoggerPhaseScope("UpdateHref", true))
                        {
                            UpdateHref(manifest, context);
                        }

                        // Afterwards, m.Item.Model.Content is always IDictionary
                        using (new LoggerPhaseScope("ApplySystemMetadata", true))
                        {
                            ApplySystemMetadata(manifest, context);
                        }

                        // Register global variables after href are all updated
                        IDictionary <string, object> globalVariables;
                        using (new LoggerPhaseScope("FeedGlobalVariables", true))
                        {
                            globalVariables = FeedGlobalVariables(templateProcessor.Tokens, manifest, context);
                        }

                        // processor to add global variable to the model
                        foreach (var m in templateProcessor.Process(manifest.Select(s => s.Item).ToList(), context, parameters.ApplyTemplateSettings, globalVariables))
                        {
                            context.ManifestItems.Add(m);
                        }
                        return(new Manifest
                        {
                            Files = context.ManifestItems.ToList(),
                            Homepages = GetHomepages(context),
                            XRefMap = ExportXRefMap(parameters, context),
                            SourceBasePath = TypeForwardedToStringExtension.ToNormalizedPath(EnvironmentContext.BaseDirectory)
                        });
                    }
                }
                finally
                {
                    if (hostServices != null)
                    {
                        foreach (var item in hostServices)
                        {
                            Cleanup(item);
                            item.Dispose();
                        }
                    }
                }
            }
        }