Skip to content

Commit a709ba8

Browse files
committed
Adjust tests, fix some bugs
1 parent 24d47df commit a709ba8

File tree

5 files changed

+219
-17
lines changed

5 files changed

+219
-17
lines changed

sources/SilkTouch/SilkTouch/Caching/CacheUtils.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ internal static void ThrowRequireHostDirectoryNeedsWrite() =>
1515
"CacheFlags.RequireHostDirectory needs FileAccess.Write due to the cache accesses being uncontrolled by "
1616
+ "the cache system."
1717
);
18+
19+
internal static string ToCacheEntryPath(this string s) =>
20+
s.Trim('\r', '\n', '\\', '/').Replace('\\', '/');
1821
}

sources/SilkTouch/SilkTouch/Caching/FileSystemArchiveCacheDirectory.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.IO.Compression;
67
using System.Text;
78
using Microsoft.Extensions.Logging;
@@ -19,13 +20,18 @@ FileSystemCacheProvider parent
1920
) : ICacheDirectory
2021
{
2122
private ZipArchive? _committed;
23+
private bool _hasCommitted;
2224
private string? _newPath;
2325
private ZipArchive? _new;
26+
private HashSet<string>? _newEntries;
2427
private SemaphoreSlim _sema = new(1, 1);
2528

2629
private async ValueTask<ZipArchive?> GetOrCreateCommittedAsync()
2730
{
28-
if (!File.Exists(committedPath) || (Flags & CacheFlags.RequireNew) == CacheFlags.RequireNew)
31+
if (
32+
!File.Exists(committedPath)
33+
|| (Flags & CacheFlags.RequireNew) == CacheFlags.RequireNew && !_hasCommitted
34+
)
2935
{
3036
parent.Logger.LogDebug(
3137
"Cache miss with key \"{0}\"! Expected ZIP archive at {1}",
@@ -48,17 +54,22 @@ FileSystemCacheProvider parent
4854
);
4955
}
5056

57+
// [MemberNotNull(nameof(_new))] <-- TODO WHY IS THE COMPILER NOT HAPPY?
58+
[MemberNotNull(nameof(_newEntries))]
5159
private async ValueTask<ZipArchive> GetOrCreateNewAsync()
5260
{
5361
if (_new is not null)
5462
{
63+
Debug.Assert(_newEntries is not null);
5564
return _new;
5665
}
5766

5867
if ((Access & FileAccess.Write) == 0)
5968
{
6069
CacheUtils.ThrowAccessException();
70+
#pragma warning disable CS8774 // Member must have a non-null value when exiting.
6171
return null!;
72+
#pragma warning restore CS8774 // Member must have a non-null value when exiting.
6273
}
6374

6475
_newPath = IOPath.GetTempFileName();
@@ -67,6 +78,7 @@ private async ValueTask<ZipArchive> GetOrCreateNewAsync()
6778
CacheKey,
6879
_newPath
6980
);
81+
_newEntries = [];
7082
return _new = await ZipArchive.CreateAsync(
7183
File.OpenWrite(_newPath),
7284
ZipArchiveMode.Create,
@@ -93,7 +105,7 @@ var entry in (await GetOrCreateCommittedAsync())?.Entries
93105
?? Enumerable.Empty<ZipArchiveEntry>()
94106
)
95107
{
96-
yield return entry.FullName;
108+
yield return entry.FullName.ToCacheEntryPath();
97109
}
98110
}
99111

@@ -105,12 +117,14 @@ public async ValueTask<Stream> GetCommittedFileAsync(string filePath)
105117
}
106118

107119
parent.Logger.LogTrace("Cache hit (\"{0}\", ZIP): {1}", CacheKey, filePath);
108-
var entry = _committed?.GetEntry(filePath) ?? throw new FileNotFoundException();
120+
var entry =
121+
_committed?.GetEntry(filePath.ToCacheEntryPath()) ?? throw new FileNotFoundException();
109122
return await entry.OpenAsync();
110123
}
111124

112125
public async ValueTask AddFileAsync(string filePath, Stream stream)
113126
{
127+
filePath = filePath.ToCacheEntryPath();
114128
if ((Access & FileAccess.Write) == 0)
115129
{
116130
CacheUtils.ThrowAccessException();
@@ -124,6 +138,7 @@ public async ValueTask AddFileAsync(string filePath, Stream stream)
124138
.CreateEntry(filePath, CompressionLevel.SmallestSize)
125139
.OpenAsync();
126140
await stream.CopyToAsync(dst);
141+
_newEntries.Add(filePath);
127142
}
128143
finally
129144
{
@@ -153,7 +168,7 @@ public async ValueTask CommitAsync()
153168
// If the user doesn't want this, they can use RequireNew.
154169
foreach (var entry in _committed.Entries)
155170
{
156-
if (@new.GetEntry(entry.FullName) is null)
171+
if (!_newEntries.Contains(entry.FullName.ToCacheEntryPath()))
157172
{
158173
parent.Logger.LogTrace(
159174
"Cache unchanged (\"{0}\", ZIP): {1}",
@@ -181,6 +196,7 @@ public async ValueTask CommitAsync()
181196

182197
await @new.DisposeAsync();
183198
_new = null;
199+
_hasCommitted = true;
184200
Debug.Assert(_newPath is not null);
185201
File.Move(_newPath, committedPath, true);
186202
}

sources/SilkTouch/SilkTouch/Caching/FileSystemCacheProvider.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@ public class FileSystemCacheProvider(ILogger<FileSystemCacheProvider> logger) :
1616

1717
static string GetCachePath(string cacheKey, CacheIntent intent)
1818
{
19+
var outDir = Path.Combine(CommonDir, ".silktouch");
20+
if (!Directory.Exists(outDir))
21+
{
22+
Directory.CreateDirectory(outDir);
23+
}
24+
1925
cacheKey = cacheKey.ToLower();
2026
var ext = intent switch
2127
{
2228
CacheIntent.ResolvedForeignInput => "stdownload",
2329
CacheIntent.StageIntermediateOutput => "stout",
2430
_ => throw new ArgumentOutOfRangeException(nameof(intent), intent, null),
2531
};
26-
return Path.Combine(CommonDir, ".silktouch", $"{cacheKey}.{ext}");
32+
return Path.Combine(outDir, $"{cacheKey}.{ext}");
2733
}
2834

2935
/// <inheritdoc />

sources/SilkTouch/SilkTouch/Caching/FileSystemDiskCacheDirectory.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ FileSystemCacheProvider parent
1616
) : ICacheDirectory
1717
{
1818
private string? _newPath;
19-
private bool _committed; // literally just for logging purposes
19+
private bool _committed;
2020

2121
public async ValueTask InitAsync()
2222
{
@@ -97,17 +97,26 @@ private string NewPath
9797
return _newPath;
9898
}
9999
}
100-
public string? Path => (Flags & CacheFlags.RequireHostDirectory) != 0 ? _newPath : null;
100+
public string? Path => (Flags & CacheFlags.RequireHostDirectory) != 0 ? NewPath : null;
101101

102102
public IAsyncEnumerable<string> GetCommittedFilesAsync()
103103
{
104104
if ((Access & FileAccess.Read) == 0)
105105
{
106106
CacheUtils.ThrowAccessException();
107107
}
108+
109+
if (
110+
!Directory.Exists(committedPath)
111+
|| ((Flags & CacheFlags.RequireNew) == CacheFlags.RequireNew && !_committed)
112+
)
113+
{
114+
return AsyncEnumerable.Empty<string>();
115+
}
116+
108117
return Directory
109118
.GetFiles(committedPath, "*", SearchOption.AllDirectories)
110-
.Select(x => IOPath.GetRelativePath(committedPath, x))
119+
.Select(x => IOPath.GetRelativePath(committedPath, x).ToCacheEntryPath())
111120
.ToAsyncEnumerable();
112121
}
113122

@@ -151,6 +160,10 @@ public async ValueTask CommitAsync()
151160
{
152161
parent.Logger.LogTrace("Erasing {0} as RequireNew is set", committedPath);
153162
Directory.Delete(committedPath, true);
163+
}
164+
165+
if (!Directory.Exists(committedPath))
166+
{
154167
Directory.CreateDirectory(committedPath);
155168
}
156169

@@ -179,7 +192,8 @@ await Task.Run(
179192
{
180193
File.Copy(
181194
x,
182-
IOPath.Combine(committedPath, IOPath.GetRelativePath(_newPath, x))
195+
IOPath.Combine(committedPath, IOPath.GetRelativePath(_newPath, x)),
196+
true
183197
);
184198
}
185199
else

0 commit comments

Comments
 (0)