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"))];
}