Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -347,24 +347,14 @@ protected override void Dispose(bool disposing)

private bool MatchesFilter(ChangeDescription changeDescription)
{
string fullPath = _fileSystem.Execute.Path.GetFullPath(Path);
if (IncludeSubdirectories)
if (!MatchesWatcherPath(changeDescription.Path))
{
if (!changeDescription.Path.StartsWith(fullPath,
_fileSystem.Execute.StringComparisonMode))
if (changeDescription.ChangeType != WatcherChangeTypes.Renamed ||
!MatchesWatcherPath(changeDescription.OldPath))
{
return changeDescription.ChangeType == WatcherChangeTypes.Renamed &&
changeDescription.OldPath?.StartsWith(fullPath,
_fileSystem.Execute.StringComparisonMode) == true;
return false;
}
}
else if (!string.Equals(
_fileSystem.Execute.Path.GetDirectoryName(changeDescription.Path),
fullPath,
_fileSystem.Execute.StringComparisonMode))
{
return false;
}

if ((NotifyFilter & changeDescription.NotifyFilters) == 0)
{
Expand All @@ -384,6 +374,23 @@ private bool MatchesFilter(ChangeDescription changeDescription)
filter));
}

private bool MatchesWatcherPath(string? path)
{
if (path == null)
{
return false;
}

string fullPath = _fileSystem.Execute.Path.GetFullPath(Path);
if (IncludeSubdirectories)
{
return path.StartsWith(fullPath, _fileSystem.Execute.StringComparisonMode);
}

return string.Equals(_fileSystem.Execute.Path.GetDirectoryName(path), fullPath,
_fileSystem.Execute.StringComparisonMode);
}

private void NotifyChange(ChangeDescription item)
{
InternalEvent?.Invoke(this, new ChangeDescriptionEventArgs(item));
Expand Down Expand Up @@ -505,16 +512,18 @@ private FileSystemEventArgs ToFileSystemEventArgs(
changeName,
out string name);

FileSystemEventArgs eventArgs = new(changeType, path, name);
if (_fileSystem.SimulationMode != SimulationMode.Native)
{
// FileSystemEventArgs implicitly combines the path in https://github.com/dotnet/runtime/blob/v8.0.4/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs
// HACK: Have to resort to Reflection to override this behavior!
string fullPath = _fileSystem.Execute.Path.Combine(path, name);
typeof(FileSystemEventArgs)
.GetField("_fullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, fullPath);
}
FileSystemEventArgs eventArgs = new(changeType, changePath, name);
// FileSystemEventArgs implicitly combines the path in https://github.com/dotnet/runtime/blob/v8.0.4/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs
// HACK: Have to resort to Reflection to override this behavior!
#if NETFRAMEWORK
typeof(FileSystemEventArgs)
.GetField("fullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, path);
#else
typeof(FileSystemEventArgs)
.GetField("_fullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, path);
#endif

return eventArgs;
}
Expand All @@ -526,40 +535,35 @@ private string TransformPathAndName(
{
string? transformedName = changeDescriptionName;
string? path = changeDescriptionPath;
if (transformedName == null ||
_fileSystem.Execute.Path.IsPathRooted(changeDescriptionName))
if (!_fileSystem.Path.IsPathRooted(Path))
{
string rootedWatchedPath = _fileSystem.Directory.GetCurrentDirectory();
if (!rootedWatchedPath.EndsWith(_fileSystem.Path.DirectorySeparatorChar))
{
rootedWatchedPath += _fileSystem.Path.DirectorySeparatorChar;
}

if (path.StartsWith(rootedWatchedPath, _fileSystem.Execute.StringComparisonMode))
{
path = path.Substring(rootedWatchedPath.Length);
}

transformedName = _fileSystem.Execute.Path.GetFileName(changeDescriptionPath);
path = _fileSystem.Execute.Path.GetDirectoryName(path);
}
else if (path.EndsWith(transformedName, _fileSystem.Execute.StringComparisonMode))
else if (transformedName == null ||
_fileSystem.Execute.Path.IsPathRooted(changeDescriptionName))
{
path = path.Substring(0, path.Length - transformedName.Length);
transformedName = _fileSystem.Execute.Path.GetFileName(changeDescriptionPath);
}

name = transformedName;
if (!_fileSystem.Path.IsPathRooted(Path))
{
string rootedWatchedPath = _fileSystem.Path.GetFullPath(Path);
if (path?.StartsWith(rootedWatchedPath, _fileSystem.Execute.StringComparisonMode) ==
true)
{
path = _fileSystem.Path.Combine(Path, path.Substring(rootedWatchedPath.Length));
}
}

return path ?? "";
}

private void TriggerRenameNotification(ChangeDescription item)
{
if (!item.Path.StartsWith(Path, _fileSystem.Execute.StringComparisonMode) &&
item.OldPath != null)
{
Deleted?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Deleted, item.OldPath, item.OldName));
}
else if (_fileSystem.Execute.IsWindows)
if (_fileSystem.Execute.IsWindows)
{
if (TryMakeRenamedEventArgs(item,
out RenamedEventArgs? eventArgs))
Expand All @@ -568,10 +572,17 @@ private void TriggerRenameNotification(ChangeDescription item)
}
else if (item.OldPath != null)
{
Deleted?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Deleted, item.OldPath, item.OldName));
Created?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Created, item.Path, item.Name));
if (MatchesWatcherPath(item.OldPath))
{
Deleted?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Deleted, item.OldPath, item.OldName));
}

if (MatchesWatcherPath(item.Path))
{
Created?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Created, item.Path, item.Name));
}
}
}
else
Expand Down Expand Up @@ -600,7 +611,7 @@ private bool TryMakeRenamedEventArgs(
changeDescription.Name,
out string name);

TransformPathAndName(
string oldPath = TransformPathAndName(
changeDescription.OldPath,
changeDescription.OldName,
out string oldName);
Expand All @@ -610,19 +621,23 @@ private bool TryMakeRenamedEventArgs(
path,
name,
oldName);
if (_fileSystem.SimulationMode != SimulationMode.Native)
{
// RenamedEventArgs implicitly combines the path in https://github.com/dotnet/runtime/blob/v8.0.4/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/RenamedEventArgs.cs
// HACK: Have to resort to Reflection to override this behavior!
string fullPath = _fileSystem.Execute.Path.Combine(path, name);
typeof(FileSystemEventArgs)
.GetField("_fullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, fullPath);
string oldFullPath = _fileSystem.Execute.Path.Combine(path, oldName);
typeof(RenamedEventArgs)
.GetField("_oldFullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, oldFullPath);
}
// RenamedEventArgs implicitly combines the path in https://github.com/dotnet/runtime/blob/v8.0.4/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/RenamedEventArgs.cs
// HACK: Have to resort to Reflection to override this behavior!
#if NETFRAMEWORK
typeof(FileSystemEventArgs)
.GetField("fullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, path);
typeof(RenamedEventArgs)
.GetField("oldFullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, oldPath);
#else
typeof(FileSystemEventArgs)
.GetField("_fullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, path);
typeof(RenamedEventArgs)
.GetField("_oldFullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, oldPath);
#endif

return _fileSystem.Execute.Path.GetDirectoryName(changeDescription.Path)?
.Equals(_fileSystem.Execute.Path.GetDirectoryName(changeDescription.OldPath),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public async Task FileSystemEventArgs_ShouldUseDirectorySeparatorFromSimulatedFi
string expectedName = fileSystem.Path.Combine(parentDirectory, directoryName);

using IFileSystemWatcher fileSystemWatcher =
fileSystem.FileSystemWatcher.New(parentDirectory);
fileSystem.FileSystemWatcher.New(fileSystem.Path.GetFullPath(parentDirectory));
using ManualResetEventSlim ms = new();
fileSystemWatcher.Created += (_, eventArgs) =>
{
Expand Down
Loading
Loading