Skip to content

Commit 93f171e

Browse files
authored
feature/config folder arg (#1580)
* Ensure we assign record with with syntax to ensure we do not update shared instances of repository * Add `repo init-config` command This allows the build to source the configuration prior to cloning and building docs-assembler repo init-config docs-assembler repo clone-all docs-assembler repo build-all On production we can lock the configuration to a commit using `--git-ref sha`. ConfigurationFileProvider will look at - {pwd}/config, development - {app_data}/config, (where init-config clones too) - embedded sources We also now log the configuration source and in case of app_data also the git reference.
1 parent 9f4acc1 commit 93f171e

File tree

9 files changed

+105
-11
lines changed

9 files changed

+105
-11
lines changed

config/assembler.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,4 @@ references:
136136
current: 9.0
137137
next: main
138138
skip: true
139+
sparse_paths: ["docs", "config"]

src/Elastic.Documentation.Configuration/Assembler/Repository.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information
44

5+
using System.Collections;
56
using System.Runtime.Serialization;
67
using YamlDotNet.Serialization;
78

@@ -44,6 +45,9 @@ public record Repository
4445
[YamlMember(Alias = "edge")]
4546
public string GitReferenceEdge { get; set; } = "main";
4647

48+
[YamlMember(Alias = "sparse_paths")]
49+
public string[] SparsePaths { get; set; } = ["docs"];
50+
4751
public string GetBranch(ContentSource contentSource) => contentSource switch
4852
{
4953
ContentSource.Current => GitReferenceCurrent,

src/Elastic.Documentation.Configuration/ConfigurationFileProvider.cs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@
44

55
using System.IO.Abstractions;
66
using Microsoft.Extensions.DependencyInjection;
7+
using NetEscapades.EnumGenerators;
78

89
namespace Elastic.Documentation.Configuration;
910

11+
[EnumExtensions]
12+
public enum ConfigurationSource
13+
{
14+
Local,
15+
Checkout,
16+
Embedded
17+
}
18+
1019
public class ConfigurationFileProvider
1120
{
1221
private readonly IFileSystem _fileSystem;
1322
private readonly string _assemblyName;
1423

24+
public ConfigurationSource ConfigurationSource { get; private set; } = ConfigurationSource.Embedded;
25+
public string? GitReference { get; }
26+
1527
public ConfigurationFileProvider(IFileSystem fileSystem)
1628
{
1729
_fileSystem = fileSystem;
@@ -22,6 +34,9 @@ public ConfigurationFileProvider(IFileSystem fileSystem)
2234
AssemblerFile = CreateTemporaryConfigurationFile("assembler.yml");
2335
NavigationFile = CreateTemporaryConfigurationFile("navigation.yml");
2436
LegacyUrlMappingsFile = CreateTemporaryConfigurationFile("legacy-url-mappings.yml");
37+
var path = GetAppDataPath("git-ref.txt");
38+
if (ConfigurationSource == ConfigurationSource.Checkout && _fileSystem.File.Exists(path))
39+
GitReference = _fileSystem.File.ReadAllText(path);
2540
}
2641

2742
private IDirectoryInfo TemporaryDirectory { get; }
@@ -45,11 +60,21 @@ private IFileInfo CreateTemporaryConfigurationFile(string fileName)
4560

4661
private StreamReader GetLocalOrEmbedded(string fileName)
4762
{
48-
var configPath = GetLocalPath(fileName);
49-
if (!_fileSystem.File.Exists(configPath))
50-
return GetEmbeddedStream(fileName);
51-
var reader = _fileSystem.File.OpenText(configPath);
52-
return reader;
63+
var localPath = GetLocalPath(fileName);
64+
var appDataPath = GetAppDataPath(fileName);
65+
if (_fileSystem.File.Exists(localPath))
66+
{
67+
ConfigurationSource = ConfigurationSource.Local;
68+
var reader = _fileSystem.File.OpenText(localPath);
69+
return reader;
70+
}
71+
if (_fileSystem.File.Exists(appDataPath))
72+
{
73+
ConfigurationSource = ConfigurationSource.Checkout;
74+
var reader = _fileSystem.File.OpenText(appDataPath);
75+
return reader;
76+
}
77+
return GetEmbeddedStream(fileName);
5378
}
5479

5580
private StreamReader GetEmbeddedStream(string fileName)
@@ -60,9 +85,11 @@ private StreamReader GetEmbeddedStream(string fileName)
6085
return reader;
6186
}
6287

63-
public static string LocalConfigurationDirectory => Path.Combine(Paths.WorkingDirectoryRoot.FullName, "config");
88+
private static string AppDataConfigurationDirectory { get; } = Path.Combine(Paths.ApplicationData.FullName, "config-clone", "config");
89+
private static string LocalConfigurationDirectory { get; } = Path.Combine(Paths.WorkingDirectoryRoot.FullName, "config");
6490

6591
private static string GetLocalPath(string file) => Path.Combine(LocalConfigurationDirectory, file);
92+
private static string GetAppDataPath(string file) => Path.Combine(AppDataConfigurationDirectory, file);
6693
}
6794

6895
public static class ConfigurationFileProviderServiceCollectionExtensions
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Reflection;
6+
using ConsoleAppFramework;
7+
using Elastic.Documentation.Configuration;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace Elastic.Documentation.Tooling.Filters;
11+
12+
public class InfoLoggerFilter(ConsoleAppFilter next, ILogger<InfoLoggerFilter> logger, ConfigurationFileProvider fileProvider) : ConsoleAppFilter(next)
13+
{
14+
public override async Task InvokeAsync(ConsoleAppContext context, Cancel cancellationToken)
15+
{
16+
logger.LogInformation("Configuration source: {ConfigurationSource}", fileProvider.ConfigurationSource.ToStringFast(true));
17+
if (fileProvider.ConfigurationSource == ConfigurationSource.Checkout)
18+
logger.LogInformation("Configuration source git reference: {ConfigurationSourceGitReference}", fileProvider.GitReference);
19+
var assemblyVersion = Assembly.GetExecutingAssembly().GetCustomAttributes<AssemblyInformationalVersionAttribute>()
20+
.FirstOrDefault()?.InformationalVersion;
21+
logger.LogInformation("Version: {Version}", assemblyVersion);
22+
await Next.InvokeAsync(context, cancellationToken);
23+
}
24+
}

src/tooling/docs-assembler/Cli/RepositoryCommands.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,39 @@ private void AssignOutputLogger()
4242
ConsoleApp.LogError = msg => _log.LogError(msg);
4343
}
4444

45+
/// <summary> Clone the configuration folder </summary>
46+
/// <param name="gitRef">The git reference of the config, defaults to 'main'</param>
47+
[Command("init-config")]
48+
public async Task<int> CloneConfigurationFolder(string? gitRef = null, Cancel ctx = default)
49+
{
50+
await using var collector = new ConsoleDiagnosticsCollector(logFactory, githubActionsService).StartAsync(ctx);
51+
52+
var fs = new FileSystem();
53+
var cachedPath = Path.Combine(Paths.ApplicationData.FullName, "config-clone");
54+
var checkoutFolder = fs.DirectoryInfo.New(cachedPath);
55+
var cloner = new RepositorySourcer(logFactory, checkoutFolder, fs, collector);
56+
57+
// relies on the embedded configuration, but we don't expect this to change
58+
var repository = assemblyConfiguration.ReferenceRepositories["docs-builder"];
59+
repository = repository with
60+
{
61+
SparsePaths = ["config"]
62+
};
63+
if (string.IsNullOrEmpty(gitRef))
64+
gitRef = "main";
65+
66+
_log.LogInformation("Cloning configuration ({GitReference})", gitRef);
67+
var checkout = cloner.CloneRef(repository, gitRef, appendRepositoryName: false);
68+
_log.LogInformation("Cloned configuration ({GitReference}) to {ConfigurationFolder}", checkout.HeadReference, checkout.Directory.FullName);
69+
70+
var gitRefInformationFile = Path.Combine(cachedPath, "config", "git-ref.txt");
71+
await fs.File.WriteAllTextAsync(gitRefInformationFile, checkout.HeadReference, ctx);
72+
73+
await collector.StopAsync(ctx);
74+
return collector.Errors;
75+
}
76+
77+
4578
/// <summary> Clones all repositories </summary>
4679
/// <param name="strict"> Treat warnings as errors and fail the build on warnings</param>
4780
/// <param name="environment"> The environment to build</param>

src/tooling/docs-assembler/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
var app = ConsoleApp.Create();
2323
app.UseFilter<ReplaceLogFilter>();
24+
app.UseFilter<InfoLoggerFilter>();
2425
app.UseFilter<StopwatchFilter>();
2526
app.UseFilter<CatchExceptionFilter>();
2627

src/tooling/docs-assembler/Sourcing/GitFacade.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public interface IGitRepository
1717
bool IsInitialized();
1818
void Pull(string branch);
1919
void Fetch(string reference);
20-
void EnableSparseCheckout(string folder);
20+
void EnableSparseCheckout(string[] folders);
2121
void DisableSparseCheckout();
2222
void Checkout(string reference);
2323
}
@@ -40,7 +40,7 @@ public class SingleCommitOptimizedGitRepository(DiagnosticsCollector collector,
4040
public bool IsInitialized() => Directory.Exists(Path.Combine(WorkingDirectory.FullName, ".git"));
4141
public void Pull(string branch) => ExecIn(EnvironmentVars, "git", "pull", "--depth", "1", "--allow-unrelated-histories", "--no-ff", "origin", branch);
4242
public void Fetch(string reference) => ExecIn(EnvironmentVars, "git", "fetch", "--no-tags", "--prune", "--no-recurse-submodules", "--depth", "1", "origin", reference);
43-
public void EnableSparseCheckout(string folder) => ExecIn(EnvironmentVars, "git", "sparse-checkout", "set", folder);
43+
public void EnableSparseCheckout(string[] folders) => ExecIn(EnvironmentVars, "git", ["sparse-checkout", "set", .. folders]);
4444
public void DisableSparseCheckout() => ExecIn(EnvironmentVars, "git", "sparse-checkout", "disable");
4545
public void Checkout(string reference) => ExecIn(EnvironmentVars, "git", "checkout", "--force", reference);
4646

src/tooling/docs-assembler/Sourcing/RepositorySourcesFetcher.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,12 @@ public class RepositorySourcer(ILoggerFactory logFactory, IDirectoryInfo checkou
130130
// </summary>
131131
// <param name="repository">The repository to clone.</param>
132132
// <param name="gitRef">The git reference to check out. Branch, commit or tag</param>
133-
public Checkout CloneRef(Repository repository, string gitRef, bool pull = false, int attempt = 1)
133+
public Checkout CloneRef(Repository repository, string gitRef, bool pull = false, int attempt = 1, bool appendRepositoryName = true)
134134
{
135-
var checkoutFolder = readFileSystem.DirectoryInfo.New(Path.Combine(checkoutDirectory.FullName, repository.Name));
135+
var checkoutFolder =
136+
appendRepositoryName
137+
? readFileSystem.DirectoryInfo.New(Path.Combine(checkoutDirectory.FullName, repository.Name))
138+
: checkoutDirectory;
136139
IGitRepository git = new SingleCommitOptimizedGitRepository(collector, checkoutFolder);
137140
if (attempt > 3)
138141
{
@@ -228,7 +231,7 @@ private static void FetchAndCheckout(IGitRepository git, Repository repository,
228231
git.DisableSparseCheckout();
229232
break;
230233
case CheckoutStrategy.Partial:
231-
git.EnableSparseCheckout("docs");
234+
git.EnableSparseCheckout(repository.SparsePaths);
232235
break;
233236
default:
234237
throw new ArgumentOutOfRangeException(nameof(repository), repository.CheckoutStrategy, null);

src/tooling/docs-builder/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
var app = ConsoleApp.Create();
1616

1717
app.UseFilter<ReplaceLogFilter>();
18+
app.UseFilter<InfoLoggerFilter>();
1819
app.UseFilter<StopwatchFilter>();
1920
app.UseFilter<CatchExceptionFilter>();
2021
app.UseFilter<CheckForUpdatesFilter>();

0 commit comments

Comments
 (0)