-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRepositoryPaths.cs
More file actions
86 lines (79 loc) · 4.19 KB
/
RepositoryPaths.cs
File metadata and controls
86 lines (79 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System.Collections.ObjectModel;
namespace IntelliTect.Multitool;
/// <summary>
/// Provides consistent environment-independent normalized pathing within a repository.
/// </summary>
public static class RepositoryPaths
{
/// <summary>
/// Name of the build variables file that is created by the build process.
/// </summary>
public const string BuildVariableFileName = "IntelliTect.MultiTool.BuildVariables.tmp";
/// <summary>
/// Holds the key value pairs of the build variables that this class can use.
/// </summary>
public static ReadOnlyDictionary<string, string?> BuildVariables { get; } = new(File.ReadAllLines(Path.Combine(Path.GetTempPath(), BuildVariableFileName))
.Select(line => line.Split("::"))
.ToDictionary(split => split[0].Trim(),
split => !string.IsNullOrEmpty(split[1]) ? split[1].Trim() : null));
/// <summary>
/// Finds the root of the repository by looking for the directory containing the .git directory.
/// Begins searching up from the current directory, and retries from the project directory if initially not found.
/// Defaults to the solution directory, if available, if the .git directory is not found.
/// </summary>
/// <returns>Full path to repo root.</returns>
public static string GetDefaultRepoRoot()
{
string gitDirectory;
DirectoryInfo? searchStartDirectory;
// If not live unit testing, try searching from current directory. But if we are this will fail, so just skip
if (!(BuildVariables.TryGetValue("BuildingForLiveUnitTesting", out string? isLiveUnitTesting)
&& isLiveUnitTesting == "true"))
{
searchStartDirectory = new(Directory.GetCurrentDirectory());
if (TrySearchForGitContainingDirectory(searchStartDirectory, out gitDirectory)
&& !string.IsNullOrWhiteSpace(gitDirectory))
{
return gitDirectory;
}
}
// Search from the project directory if we are live unit testing or if the initial search failed.
if (BuildVariables.TryGetValue("ProjectPath", out string? projectPath))
{
searchStartDirectory = new FileInfo(projectPath).Directory;
if (TrySearchForGitContainingDirectory(searchStartDirectory, out gitDirectory)
&& !string.IsNullOrWhiteSpace(gitDirectory))
{
return gitDirectory;
}
}
// If all this fails, try returning the Solution Directory in hopes that is in the root of the repo.
if (BuildVariables.TryGetValue("SolutionDir", out string? solutionDir) && !string.IsNullOrWhiteSpace(solutionDir))
{
return Directory.Exists(solutionDir) ? solutionDir : throw new InvalidOperationException($"SolutionDir is not a valid directory.");
}
throw new InvalidOperationException("Could not find the repo root directory from the current directory. Current directory is expected to be the repoRoot sub directory.");
}
/// <summary>
/// Searches up from the <paramref name="searchStartDirectory"/> looking for a .git directory.
/// </summary>
/// <param name="searchStartDirectory">The directory to start searching from, will search up.</param>
/// <param name="gitParentDirectory">The parent directory to the .git directory.</param>
/// <returns><c>true</c> if the directory <paramref name="gitParentDirectory" /> was found successfully; otherwise, false.</returns>
public static bool TrySearchForGitContainingDirectory(DirectoryInfo? searchStartDirectory, out string gitParentDirectory)
{
while (searchStartDirectory is not null)
{
DirectoryInfo[] subDirectories = searchStartDirectory.GetDirectories(".git");
// Also check for a .git file (present in git worktrees as a gitfile pointer)
if (subDirectories.Length > 0 || File.Exists(Path.Combine(searchStartDirectory.FullName, ".git")))
{
gitParentDirectory = searchStartDirectory.FullName;
return true;
}
searchStartDirectory = searchStartDirectory.Parent;
}
gitParentDirectory = string.Empty;
return false;
}
}