Skip to content

Commit 6ab7a01

Browse files
committed
Merge branch 'database-cleanup-nobinarystream' into 'main'
Cleanup database no longer uses Serialization.Formatters.Binary See merge request Sharpmake/sharpmake!573
2 parents eca8102 + b606eae commit 6ab7a01

File tree

1 file changed

+78
-41
lines changed

1 file changed

+78
-41
lines changed

Sharpmake/Util.cs

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using System.Runtime.Versioning;
1717
using System.Text;
1818
using System.Text.Json;
19-
using System.Text.Json.Serialization;
2019
using System.Text.RegularExpressions;
2120
using Microsoft.VisualStudio.Setup.Configuration;
2221
using Microsoft.Win32;
@@ -278,73 +277,120 @@ public static void LogWrite(string msg, params object[] args)
278277

279278
public static List<string> FilesAlternatesAutoCleanupDBSuffixes = new List<string>(); // The alternates db suffixes using by other context
280279
private static List<string> _FilesAlternatesAutoCleanupDBFullPaths = new List<string>();
281-
public static string FilesAutoCleanupDBPath = string.Empty;
282-
public static string FilesAutoCleanupDBSuffix = string.Empty; // Current auto-cleanup suffix for the database.
280+
public static string FilesAutoCleanupDBPath { get; set; } = string.Empty;
281+
public static string FilesAutoCleanupDBSuffix { get; set; } = string.Empty; // Current auto-cleanup suffix for the database.
283282
internal static bool s_forceFilesCleanup = false;
284283
internal static string s_overrideFilesAutoCleanupDBPath;
285-
public static bool FilesAutoCleanupActive = false;
286-
public static TimeSpan FilesAutoCleanupDelay = TimeSpan.Zero;
284+
285+
public static bool FilesAutoCleanupActive { get; set; }
286+
public static TimeSpan FilesAutoCleanupDelay { get; set; } = TimeSpan.Zero;
287287
public static HashSet<string> FilesToBeExplicitlyRemovedFromDB = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
288288
public static HashSet<string> FilesAutoCleanupIgnoredEndings = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
289289
private const string s_filesAutoCleanupDBPrefix = "sharpmakeautocleanupdb";
290-
private enum DBVersion { Version = 3 };
291290

292291
private static JsonSerializerOptions GetCleanupDatabaseJsonSerializerOptions()
293292
{
294293
return new JsonSerializerOptions()
295294
{
296295
AllowTrailingCommas = true,
297296
PropertyNamingPolicy = null,
298-
WriteIndented = false,
297+
WriteIndented = true,
299298
};
300299
}
301300

301+
private class CleanupDatabaseContent
302+
{
303+
public enum DBVersions
304+
{
305+
BinaryFormatterVersion = 3, // Json in a binary formatter - Deprecated - Support will be removed in the first version released after dec 31th 2024
306+
JsonVersion = 4, // New format - simple json
307+
CurrentVersion = JsonVersion
308+
};
309+
310+
public DBVersions DBVersion { get; set; }
311+
public object Data { get; set; }
312+
}
313+
302314
private static Dictionary<string, DateTime> ReadCleanupDatabase(string databaseFilename)
303315
{
304-
Dictionary<string, DateTime> dbFiles = null;
305-
if (File.Exists(databaseFilename))
316+
// DEPRECATED CODE - TO BE REMOVED AFTER DEC 31TH 2024
317+
string oldDatabaseFormatFilename = Path.ChangeExtension(databaseFilename, ".bin");
318+
if (File.Exists(oldDatabaseFormatFilename))
306319
{
307320
try
308321
{
309322
// Read database - This is simply a simple binary file containing the list of file and a version number.
310-
using (Stream readStream = new FileStream(databaseFilename, FileMode.Open, FileAccess.Read, FileShare.None))
323+
using (Stream readStream = new FileStream(oldDatabaseFormatFilename, FileMode.Open, FileAccess.Read, FileShare.None))
311324
using (BinaryReader binReader = new BinaryReader(readStream))
312325
{
313326
// Validate version number
314327
int version = binReader.ReadInt32();
315-
if (version == (int)DBVersion.Version)
328+
if (version == (int)CleanupDatabaseContent.DBVersions.BinaryFormatterVersion)
316329
{
317330
// Read the list of files.
318331
IFormatter formatter = new BinaryFormatter();
319332
string dbAsJson = binReader.ReadString();
320333

321334
var tmpDbFiles = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, DateTime>>(dbAsJson, GetCleanupDatabaseJsonSerializerOptions());
322-
dbFiles = tmpDbFiles.ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.InvariantCultureIgnoreCase);
335+
var dbFiles = tmpDbFiles.ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.InvariantCultureIgnoreCase);
336+
337+
// Converting to new format.
338+
WriteCleanupDatabase(databaseFilename, dbFiles);
339+
return dbFiles;
323340
}
324341
else
325342
{
326343
LogWrite("Warning: found cleanup database in incompatible format v{0}, skipped.", version);
327344
}
345+
}
346+
}
347+
catch
348+
{
349+
// nothing to do.
350+
}
351+
finally
352+
{
353+
TryDeleteFile(oldDatabaseFormatFilename);
354+
}
355+
}
356+
// END DEPRECATED CODE
357+
358+
if (File.Exists(databaseFilename))
359+
{
360+
try
361+
{
362+
string jsonString = File.ReadAllText(databaseFilename);
363+
var versionedDB = System.Text.Json.JsonSerializer.Deserialize<CleanupDatabaseContent>(jsonString);
364+
if (versionedDB.DBVersion == CleanupDatabaseContent.DBVersions.JsonVersion)
365+
{
366+
// Deserialize the Database to a dictionary
367+
var tmpDbFiles = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, DateTime>>(versionedDB.Data.ToString(), GetCleanupDatabaseJsonSerializerOptions());
328368

329-
readStream.Close();
369+
// Convert the dictionary to a case insensitive dictionary
370+
var dbFiles = tmpDbFiles.ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.InvariantCultureIgnoreCase);
371+
372+
return dbFiles;
373+
}
374+
else
375+
{
376+
LogWrite($"Cleanup database version {versionedDB.DBVersion} is not supported. Ignoring database");
330377
}
331378
}
332379
catch
333380
{
334-
// File is likely corrupted.
335-
// This is no big deal except that cleanup won't occur.
336-
dbFiles = null;
381+
// DB File is likely corrupted.
382+
// This is no big deal except that cleanup won't occur and this could result in files not written by the current Sharpmake run to not being deleted.
337383
}
338384
}
339-
return dbFiles;
385+
return null;
340386
}
341387

342388
private static string GetDatabaseFilename(string dbSuffix)
343389
{
344390
if (!string.IsNullOrWhiteSpace(s_overrideFilesAutoCleanupDBPath))
345391
return s_overrideFilesAutoCleanupDBPath;
346392

347-
string databaseFilename = Path.Combine(FilesAutoCleanupDBPath, $"{s_filesAutoCleanupDBPrefix}{dbSuffix}.bin");
393+
string databaseFilename = Path.Combine(FilesAutoCleanupDBPath, $"{s_filesAutoCleanupDBPrefix}{dbSuffix}.json");
348394
return databaseFilename;
349395
}
350396

@@ -475,35 +521,26 @@ internal static void ExecuteFilesAutoCleanup(bool addDBToAlternateDB)
475521
}
476522
}
477523

478-
// Write database if needed
479-
if (newDbFiles.Count > 0)
480-
{
481-
using (Stream writeStream = new FileStream(databaseFilename, FileMode.Create, FileAccess.Write, FileShare.None))
482-
using (BinaryWriter binWriter = new BinaryWriter(writeStream))
483-
{
484-
// Write version number
485-
int version = (int)DBVersion.Version;
486-
binWriter.Write(version);
487-
488-
// Write the list of files.
489-
string dbAsJson = System.Text.Json.JsonSerializer.Serialize(newDbFiles, GetCleanupDatabaseJsonSerializerOptions());
490-
binWriter.Write(dbAsJson);
491-
binWriter.Flush();
492-
}
493-
494-
if (addDBToAlternateDB)
495-
_FilesAlternatesAutoCleanupDBFullPaths.Add(databaseFilename);
496-
}
497-
else
498-
{
499-
TryDeleteFile(databaseFilename);
500-
}
524+
WriteCleanupDatabase(databaseFilename, newDbFiles);
525+
if (addDBToAlternateDB)
526+
_FilesAlternatesAutoCleanupDBFullPaths.Add(databaseFilename);
501527

502528
// We are done! Clear the list of files to avoid problems as this context is now considered as complete.
503529
// For example if generating debug solution and then executing normal generation
504530
s_writtenFiles.Clear();
505531
}
506532

533+
private static void WriteCleanupDatabase(string databaseFilename, Dictionary<string, DateTime> generatedFiles)
534+
{
535+
CleanupDatabaseContent dbContent = new CleanupDatabaseContent
536+
{
537+
DBVersion = CleanupDatabaseContent.DBVersions.CurrentVersion,
538+
Data = generatedFiles
539+
};
540+
string jsonString = System.Text.Json.JsonSerializer.Serialize(dbContent, GetCleanupDatabaseJsonSerializerOptions());
541+
File.WriteAllText(databaseFilename, jsonString);
542+
}
543+
507544
public static string WinFormSubTypesDbPath = string.Empty;
508545
private static readonly string s_winFormSubTypesDbPrefix = "winformssubtypesdb";
509546

0 commit comments

Comments
 (0)