Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LocalPackages config to _generated_local (no CI needed for gen code) #20504

Merged
merged 4 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,4 @@ _dotnetsdk/
# BuildConfigGen files
FilesOverriddenForConfigGoHereREADME.txt

_generated_local/
160 changes: 150 additions & 10 deletions BuildConfigGen/EnsureUpdateModeVerifier.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.ComponentModel.Design;
using System.Diagnostics;
using System.IO;
using System.Security.AccessControl;

namespace BuildConfigGen
Expand All @@ -10,15 +11,17 @@ internal class EnsureUpdateModeVerifier
// if any changes would be made to output, verification should fail
// check the contents of VerifyErrors for verification errors

private readonly bool verifyOnly;
private bool verifyState;
private readonly bool verifyFromConstructor;
private List<string> VerifyErrors = new List<string>();
internal Dictionary<string, string> CopiedFilesToCheck = new Dictionary<string, string>();
internal Dictionary<string, string> RedirectedToTempl = new Dictionary<string, string>();
private HashSet<string> tempsToKeep = new HashSet<string>();

public EnsureUpdateModeVerifier(bool verifyOnly)
{
this.verifyOnly = verifyOnly;
this.verifyState = verifyOnly;
this.verifyFromConstructor = verifyOnly;
}

public IEnumerable<string> GetVerifyErrors(bool skipContentCheck)
Expand All @@ -30,7 +33,6 @@ public IEnumerable<string> GetVerifyErrors(bool skipContentCheck)

if (!skipContentCheck)
{

foreach (var r in CopiedFilesToCheck)
{
string? sourceFile;
Expand Down Expand Up @@ -90,9 +92,9 @@ public void CleanupTempFiles()
}
}

if (count > 0 && !verifyOnly)
if (count > 0 && !verifyFromConstructor)
{
throw new Exception("Expected RedirectedToTemp to be empty when !verifyOnly");
throw new Exception("Expected RedirectedToTemp to be empty when !verifyFromConstructor");
}
}
finally
Expand All @@ -105,6 +107,8 @@ public void CleanupTempFiles()

internal void Copy(string sourceFileName, string destFileName, bool overwrite)
{
bool verifyOnly = UseVerifyOnlyForFile(destFileName);

if (verifyOnly)
{
if (File.Exists(destFileName))
Expand Down Expand Up @@ -138,6 +142,16 @@ internal void Copy(string sourceFileName, string destFileName, bool overwrite)

internal void Move(string sourceFileName, string destFileName)
{
bool verifyOnlySource = UseVerifyOnlyForFile(sourceFileName);
bool verifyOnlyDest = UseVerifyOnlyForFile(destFileName);

if (verifyOnlySource != verifyOnlyDest)
{
throw new Exception($"BUG: both source and dest must be unconditional path or not sourceFileName={sourceFileName} destFileName={destFileName}");
}

var verifyOnly = verifyOnlySource || verifyOnlyDest;

if (verifyOnly)
{
// verification won't pass if we encounter a move
Expand All @@ -160,6 +174,8 @@ internal void Move(string sourceFileName, string destFileName)

internal void WriteAllText(string path, string contents, bool suppressValidationErrorIfTargetPathDoesntExist)
{
bool verifyOnly = UseVerifyOnlyForFile(path);

if (verifyOnly)
{
if (File.Exists(path))
Expand Down Expand Up @@ -205,6 +221,8 @@ private string NormalizeFile(string file)

internal void DirectoryCreateDirectory(string path, bool suppressValidationErrorIfTargetPathDoesntExist)
{
bool verifyOnly = UseVerifyOnlyForPath(path);

if (verifyOnly)
{
if (!Directory.Exists(path))
Expand All @@ -228,6 +246,8 @@ internal void DirectoryCreateDirectory(string path, bool suppressValidationError

internal string FileReadAllText(string filePath)
{
bool verifyOnly = UseVerifyOnlyForFile(filePath);

if (verifyOnly)
{
string targetFile = ResolveFile(filePath);
Expand All @@ -240,8 +260,10 @@ internal string FileReadAllText(string filePath)
}
}

internal string [] FileReadAllLines(string filePath)
internal string[] FileReadAllLines(string filePath)
{
bool verifyOnly = UseVerifyOnlyForFile(filePath);

if (verifyOnly)
{
string targetFile = ResolveFile(filePath);
Expand All @@ -263,7 +285,7 @@ internal bool FilesEqual(string sourcePath, string targetPath)

private string ResolveFile(string filePath)
{
if(!verifyOnly)
if (!UseVerifyOnlyForFile(filePath))
{
return filePath;
}
Expand Down Expand Up @@ -295,20 +317,138 @@ private string ResolveFile(string filePath)

internal void DeleteDirectoryRecursive(string path)
{
if(verifyOnly)
bool verify = UseVerifyOnlyForPath(path);

if (verify)
{
if(Directory.Exists(path))
if (Directory.Exists(path))
{
VerifyErrors.Add($"Expected directory {path} to not exist");
}
}
else
{
if(Directory.Exists(path))
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
}
}

private bool UseVerifyOnlyForFile(string file)
{
return UseVerifyOnlyInternal(file, true);
}

private bool UseVerifyOnlyForPath(string path)
{
return UseVerifyOnlyInternal(path, false);
}

private bool UseVerifyOnlyInternal(string path, bool trueForFile)
{
EnsureState();

/*
// if verifyOnly state
if (verifyState)
{
return true;
}*/

// if !verifyOnly was passed to constructor, unconditional writes everywhere
if (!verifyFromConstructor)
{
return false;
}

// if uncondo
if (allowedUnconditionalPath is null)
{
return verifyState;
}

if (trueForFile ? IsSubFile(allowedUnconditionalPath, path) : IsSubPath(allowedUnconditionalPath, path))
{
return false;
}
else
{
return true;
}
}

string? allowedUnconditionalPath;

internal void StartUnconditionalWrites(string allowedUnconditionalPath)
{
EnsureState();

if(verifyState != verifyFromConstructor)
{
throw new Exception($"BUG: expected verifyState {verifyState} == verifyFromConstructor {verifyFromConstructor}");
}

if (!verifyFromConstructor)
{
return;
}

verifyState = false;
this.allowedUnconditionalPath = allowedUnconditionalPath;
}

internal void ResumeWriteBehavior()
{
EnsureState();

if (!verifyFromConstructor)
{
return;
}

verifyState = verifyFromConstructor;
this.allowedUnconditionalPath = null;
}

private void EnsureState()
{
if(!verifyFromConstructor && verifyState)
{
throw new Exception("BUG: verifyState cannot be true if verifyFromConstructor is false");
}

if (verifyFromConstructor)
{
if (this.allowedUnconditionalPath is null && !verifyState)
{
throw new Exception($"BUG: expected allowedUnconditionalPath={allowedUnconditionalPath} to be not null when !verifyState=={!verifyState}");
}
}
else
{
if (this.allowedUnconditionalPath is not null)
{
throw new Exception($"BUG: expected allowedUnconditionalPath={allowedUnconditionalPath} to be null");
}
}
}

// generaetd by copilot 20240926
static bool IsSubPath(string mainPath, string subPath)
{
var mainDirectory = new DirectoryInfo(mainPath).FullName;
var subDirectory = new DirectoryInfo(subPath).FullName;

return subDirectory.StartsWith(mainDirectory, StringComparison.OrdinalIgnoreCase);
}

static bool IsSubFile(string mainPath, string subFile)
{
var mainDirectory = new DirectoryInfo(mainPath).FullName;
var subDirectory = new FileInfo(subFile).FullName;

return subDirectory.StartsWith(mainDirectory, StringComparison.OrdinalIgnoreCase);
}
}
}
47 changes: 44 additions & 3 deletions BuildConfigGen/GitUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,51 @@ internal static string GetGitRootPath(string currentDir)
}
}

internal static IEnumerable<string> GetNonIgnoredFileListFromPath(string taskTarget)
internal static IEnumerable<string> GetNonIgnoredFileListFromPath(string gitRoot, string taskTarget)
{
if(!Directory.Exists(taskTarget))
string gitIgnorePathBak = Path.Combine(gitRoot, ".gitignore.bak");
string gitIgnore = Path.Combine(gitRoot, ".gitignore");

bool needsGitIgnoreUpdate = taskTarget.Contains("/_generated_local/") || taskTarget.Contains(@"\_generated_local\");

string? gitIgnoreContent = null;

if (needsGitIgnoreUpdate)
{
gitIgnoreContent = File.ReadAllText(gitIgnore);
const string genertedLocalPath = "_generated_local/";

if (!gitIgnoreContent.Contains(genertedLocalPath))
{
throw new Exception("Expected " + genertedLocalPath + " in " + gitIgnore);
}

gitIgnoreContent = gitIgnoreContent.Replace(genertedLocalPath, "");

File.Copy(gitIgnore, gitIgnorePathBak, true);
}

try
{
if (needsGitIgnoreUpdate)
{
File.WriteAllText(gitIgnore, gitIgnoreContent);
}

return GetNonIgnoredFileListFromPathInner(taskTarget);
}
finally
{
if (needsGitIgnoreUpdate)
{
File.Move(gitIgnorePathBak, gitIgnore, true);
}
}
}

private static IEnumerable<string> GetNonIgnoredFileListFromPathInner(string taskTarget)
{
if (!Directory.Exists(taskTarget))
{
throw new Exception($"{nameof(taskTarget)}=={taskTarget} doesn't exist");
}
Expand All @@ -137,7 +179,6 @@ internal static IEnumerable<string> GetNonIgnoredFileListFromPath(string taskTar
return paths;
}


private static IEnumerable<string> GitLsFiles(string taskTarget)
{
if (!Directory.Exists(taskTarget))
Expand Down
Loading