public ConfigurationFile()

in src/Elastic.Documentation.Configuration/Builder/ConfigurationFile.cs [62:164]


	public ConfigurationFile(IDocumentationContext context)
	{
		_context = context;
		ScopeDirectory = context.ConfigurationPath.Directory!;
		if (!context.ConfigurationPath.Exists)
		{
			Project = "unknown";
			context.EmitWarning(context.ConfigurationPath, "No configuration file found");
			return;
		}

		var sourceFile = context.ConfigurationPath;
		var redirectFileName = sourceFile.Name.StartsWith('_') ? "_redirects.yml" : "redirects.yml";
		var redirectFileInfo = sourceFile.FileSystem.FileInfo.New(Path.Combine(sourceFile.Directory!.FullName, redirectFileName));
		var redirectFile = new RedirectFile(redirectFileInfo, _context);
		Redirects = redirectFile.Redirects;

		var reader = new YamlStreamReader(sourceFile, _context.Collector);
		try
		{
			foreach (var entry in reader.Read())
			{
				switch (entry.Key)
				{
					case "project":
						Project = reader.ReadString(entry.Entry);
						break;
					case "max_toc_depth":
						MaxTocDepth = int.TryParse(reader.ReadString(entry.Entry), out var maxTocDepth) ? maxTocDepth : 1;
						break;
					case "dev_docs":
						DevelopmentDocs = bool.TryParse(reader.ReadString(entry.Entry), out var devDocs) && devDocs;
						break;
					case "exclude":
						var excludes = YamlStreamReader.ReadStringArray(entry.Entry);
						Exclude = [.. excludes.Where(s => !string.IsNullOrEmpty(s)).Select(Glob.Parse)];
						break;
					case "cross_links":
						CrossLinkRepositories = [.. YamlStreamReader.ReadStringArray(entry.Entry)];
						break;
					case "extensions":
						Extensions = new([.. YamlStreamReader.ReadStringArray(entry.Entry)]);
						break;
					case "subs":
						_substitutions = reader.ReadDictionary(entry.Entry);
						break;
					case "toc":
						// read this later
						break;
					case "products":
						if (entry.Entry.Value is not YamlSequenceNode sequence)
						{
							reader.EmitError("products must be a sequence", entry.Entry.Value);
							break;
						}

						foreach (var node in sequence.Children.OfType<YamlMappingNode>())
						{
							YamlScalarNode? productId = null;
							foreach (var child in node.Children)
							{
								if (child.Key is YamlScalarNode { Value: "id" } && child.Value is YamlScalarNode scalarNode)
								{
									productId = scalarNode;
									break;
								}
							}
							if (productId?.Value is null)
							{
								reader.EmitError("products must contain an id", node);
								break;
							}

							if (!Builder.Products.AllById.ContainsKey(productId.Value))
								reader.EmitError($"Product \"{productId.Value}\" not found in the product list. {new Suggestion(Builder.Products.All.Select(p => p.Id).ToHashSet(), productId.Value).GetSuggestionQuestion()}", node);
							else
								_ = Products.Add(productId.Value);
						}
						break;
					case "features":
						_features = reader.ReadDictionary(entry.Entry).ToDictionary(k => k.Key, v => bool.Parse(v.Value), StringComparer.OrdinalIgnoreCase);
						break;
					case "external_hosts":
						reader.EmitWarning($"{entry.Key} has been deprecated and will be removed", entry.Key);
						break;
					default:
						reader.EmitWarning($"{entry.Key} is not a known configuration", entry.Key);
						break;
				}
			}

			var toc = new TableOfContentsConfiguration(this, sourceFile, ScopeDirectory, _context, 0, "");
			TableOfContents = toc.TableOfContents;
			Files = toc.Files;
		}
		catch (Exception e)
		{
			reader.EmitError("Could not load docset.yml", e);
			throw;
		}

		Globs = [.. ImplicitFolders.Select(f => Glob.Parse($"{f}{Path.DirectorySeparatorChar}*.md"))];
	}