Skip to content

Commit 3bf981d

Browse files
committed
Allow preserving skips from init upstream file
Once a repo has been initialized from an upstream .netconfig, it basically loses its "memory" that it originally came from it. This means that subsequent (new) files in that repo, which may be added as skip=true in the seed .netconfig would be ignored on subsequent syncs and cause files to be synced that should not. By specifying the new init url again when syncing, skipped files in upsteam will be honored before any sync happens.
1 parent b0aaf44 commit 3bf981d

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

src/File/Help.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Actions
99
sync synchronizes with remote URLs, deleting local files and directories as needed
1010
update updates local files from remote URLs, does not prune deleted remote files
1111

12+
Options
13+
sync --init [url] honor new skip entries in an upstream init .netconfig
14+
1215
Status
1316
= <- [url] remote file equals local file
1417
✓ <- [url] local file updated with remote file

src/File/Program.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,21 @@ static async Task<int> Main(string[] args)
4444
// Remove first arg which is the command to use.
4545
extraArgs.RemoveAt(0);
4646

47+
// Handle --init [url] option for the sync command.
48+
if (command is SyncCommand sync &&
49+
extraArgs.FindIndex(a => a == "--init") is var index && index >= 0)
50+
{
51+
if (index + 1 < extraArgs.Count && !extraArgs[index + 1].StartsWith('-'))
52+
{
53+
sync.InitUrl = extraArgs[index + 1];
54+
extraArgs.RemoveRange(index, 2);
55+
}
56+
else
57+
{
58+
extraArgs.RemoveAt(index);
59+
}
60+
}
61+
4762
// Add remainder arguments as if they were just files or urls provided
4863
// to the command. Allows skipping the -f|-u switches.
4964
var skip = false;

src/File/SyncCommand.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,66 @@
11
using System;
22
using System.IO;
33
using System.Linq;
4+
using System.Threading.Tasks;
5+
using ColoredConsole;
46
using DotNetConfig;
57

68
namespace Devlooped;
79

810
class SyncCommand(Config configuration) : UpdateCommand(configuration)
911
{
12+
/// <summary>
13+
/// Optional URL to a remote .netconfig whose skip=true entries are merged into
14+
/// the local config before the sync runs (local entries always take precedence).
15+
/// </summary>
16+
public string? InitUrl { get; set; }
17+
18+
public override async Task<int> ExecuteAsync()
19+
{
20+
if (InitUrl != null)
21+
{
22+
var tempConfig = Path.GetTempFileName();
23+
var tempFile = Path.GetTempFileName();
24+
try
25+
{
26+
var addCmd = new AddCommand(Config.Build(tempConfig));
27+
addCmd.Files.Add(new FileSpec(tempFile, new Uri(InitUrl)));
28+
29+
ColorConsole.WriteLine("Downloading init config file(s)...".Yellow());
30+
await addCmd.ExecuteAsync();
31+
32+
var remoteConfig = Config.Build(tempFile);
33+
var localConfig = Configuration;
34+
35+
foreach (var group in remoteConfig
36+
.Where(x => x.Level == null && x.Section == "file" && x.Subsection != null)
37+
.GroupBy(x => x.Subsection!))
38+
{
39+
var path = group.Key;
40+
if (remoteConfig.GetBoolean("file", path, "skip") != true)
41+
continue;
42+
43+
// Local entry takes precedence — only add skip if no local entry exists
44+
if (localConfig.Where(x => x.Section == "file" && x.Subsection == path).Any())
45+
continue;
46+
47+
var url = remoteConfig.GetString("file", path, "url");
48+
if (url != null)
49+
localConfig = localConfig.SetString("file", path, "url", url);
50+
51+
localConfig = localConfig.SetBoolean("file", path, "skip", true);
52+
}
53+
}
54+
finally
55+
{
56+
File.Delete(tempConfig);
57+
File.Delete(tempFile);
58+
}
59+
}
60+
61+
return await base.ExecuteAsync();
62+
}
63+
1064
protected override bool OnRemoteUrlMissing(FileSpec spec)
1165
{
1266
// If the file exists locally, delete it. Remove the config entry.

0 commit comments

Comments
 (0)