-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle changes to the repository folder as they happen, rather than rebuilding the entire menu evey time it's opened.
- Loading branch information
Showing
6 changed files
with
224 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,21 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.IO; | ||
|
||
namespace GitMan | ||
{ | ||
internal class Repository | ||
{ | ||
private readonly DirectoryInfo _directoryInfo; | ||
public string Name { get; } | ||
public string FullName { get; } | ||
|
||
private Repository(DirectoryInfo directoryInfo) | ||
{ | ||
_directoryInfo = directoryInfo; | ||
Name = directoryInfo.Name; | ||
FullName = directoryInfo.FullName; | ||
} | ||
|
||
public static Repository Load(DirectoryInfo directoryInfo) | ||
{ | ||
return new Repository(directoryInfo); | ||
} | ||
|
||
public string Name => _directoryInfo.Name; | ||
|
||
public string FullName => _directoryInfo.FullName; | ||
|
||
public IEnumerable<FileInfo> SolutionFiles => _directoryInfo.EnumerateFiles("*.sln", SearchOption.AllDirectories); | ||
|
||
public bool IsVsCodeProject() | ||
{ | ||
var subDirectories = _directoryInfo.EnumerateDirectories(); | ||
var hasVsCodeDirectory = subDirectories.Any(IsVsCodeDirectory); | ||
return hasVsCodeDirectory; | ||
} | ||
|
||
private static bool IsVsCodeDirectory(DirectoryInfo directoryInfo) | ||
{ | ||
const string vsCodeDirectoryName = ".vscode"; | ||
|
||
var isVsCodeDirectory = string.Equals( | ||
directoryInfo.Name, | ||
vsCodeDirectoryName, | ||
StringComparison.OrdinalIgnoreCase); | ||
|
||
return isVsCodeDirectory; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
namespace GitMan | ||
{ | ||
internal class RepositoryDirectory : IDisposable, IEnumerable<Repository> | ||
{ | ||
private readonly DirectoryInfo _directoryInfo; | ||
private readonly Dictionary<string, Repository> _repositories; | ||
private readonly FileSystemWatcher _watcher; | ||
|
||
public RepositoryDirectory(DirectoryInfo directoryInfo) | ||
{ | ||
_directoryInfo = directoryInfo; | ||
|
||
_watcher = new FileSystemWatcher(directoryInfo.FullName); | ||
_watcher.Changed += HandleChange; | ||
_watcher.Created += HandleChange; | ||
_watcher.Deleted += HandleChange; | ||
_watcher.Renamed += HandleChange; | ||
_watcher.EnableRaisingEvents = true; | ||
|
||
_repositories = BuildIndex(); | ||
} | ||
|
||
public delegate void RepositoryAddedHandler(Repository repository); | ||
public delegate void RepositoryRenamedHandler(Repository oldRepository, Repository newRepository); | ||
public delegate void RepositoryRemovedHandler(Repository repository); | ||
|
||
public event RepositoryAddedHandler Added; | ||
public event RepositoryRenamedHandler Renamed; | ||
public event RepositoryRemovedHandler Removed; | ||
|
||
private Dictionary<string, Repository> BuildIndex() | ||
{ | ||
var index = new Dictionary<string, Repository>(); | ||
|
||
foreach (var subDirectoryInfo in _directoryInfo.EnumerateDirectories()) | ||
{ | ||
if (IsGitRepository(subDirectoryInfo)) | ||
{ | ||
var repository = Repository.Load(subDirectoryInfo); | ||
index[subDirectoryInfo.Name] = repository; | ||
} | ||
} | ||
|
||
return index; | ||
} | ||
|
||
private void HandleChange(object sender, FileSystemEventArgs eventArgs) | ||
{ | ||
var oldName = eventArgs is RenamedEventArgs rename ? rename.OldName : eventArgs.Name; | ||
var newName = eventArgs.Name; | ||
HandleChange(oldName, newName); | ||
} | ||
|
||
private bool TryGetDirectory(string name, out DirectoryInfo directory) | ||
{ | ||
directory = _directoryInfo.EnumerateDirectories().SingleOrDefault(dir => dir.Name == name); | ||
return directory != default; | ||
} | ||
|
||
private bool WasRepository(string directoryName, out Repository repository) | ||
{ | ||
if (directoryName == null) | ||
{ | ||
repository = null; | ||
return false; | ||
} | ||
|
||
return _repositories.TryGetValue(directoryName, out repository); | ||
} | ||
|
||
private bool IsRepository(string directoryName, out Repository repository) | ||
{ | ||
if (!TryGetDirectory(directoryName, out var directory)) | ||
{ | ||
repository = null; | ||
return false; | ||
} | ||
|
||
if (IsGitRepository(directory)) | ||
{ | ||
repository = Repository.Load(directory); | ||
return true; | ||
} | ||
|
||
repository = null; | ||
return false; | ||
} | ||
|
||
private void HandleChange(string oldDirectoryName, string newDirectoryName) | ||
{ | ||
var wasRepository = WasRepository(oldDirectoryName, out var oldRepository); | ||
var isRepository = IsRepository(newDirectoryName, out var newRepository); | ||
var isNameChanged = !string.Equals(oldDirectoryName, newDirectoryName, StringComparison.OrdinalIgnoreCase); | ||
|
||
if (wasRepository && isRepository) | ||
{ | ||
if (isNameChanged) | ||
{ | ||
_repositories.Remove(oldDirectoryName); | ||
_repositories[newRepository.Name] = newRepository; | ||
Renamed?.Invoke(oldRepository, newRepository); | ||
} | ||
} | ||
else if (wasRepository) | ||
{ | ||
_repositories.Remove(oldDirectoryName); | ||
Removed?.Invoke(oldRepository); | ||
} | ||
else if (isRepository) | ||
{ | ||
_repositories[newRepository.Name] = newRepository; | ||
Added?.Invoke(newRepository); | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_watcher.Dispose(); | ||
} | ||
|
||
private static bool IsGitRepository(DirectoryInfo directoryInfo) | ||
{ | ||
var subDirectories = directoryInfo.EnumerateDirectories(); | ||
var hasGitDirectory = subDirectories.Any(IsGitDirectory); | ||
return hasGitDirectory; | ||
} | ||
|
||
private static bool IsGitDirectory(DirectoryInfo directoryInfo) | ||
{ | ||
const string gitDirectoryName = ".git"; | ||
|
||
var isGitDirectory = string.Equals( | ||
directoryInfo.Name, | ||
gitDirectoryName, | ||
StringComparison.OrdinalIgnoreCase); | ||
|
||
return isGitDirectory; | ||
} | ||
|
||
public int Count => _repositories.Count; | ||
|
||
public IEnumerator<Repository> GetEnumerator() => _repositories.Values.GetEnumerator(); | ||
|
||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
} | ||
} |
Oops, something went wrong.