Skip to content

Commit

Permalink
Merge pull request #908 from daniel-chambers/fix-watcher-paths
Browse files Browse the repository at this point in the history
Fixed WatchChanges not properly removing subdirectories from watch list
  • Loading branch information
forki committed Aug 13, 2015
2 parents 651aeff + 0263949 commit 70ec26f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
23 changes: 14 additions & 9 deletions src/app/FakeLib/ChangeWatcher.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ let private handleWatcherEvents (status : FileStatus) (onChange : FileChange ->
Name = e.Name
Status = status })

let private calcDirsToWatch fileIncludes =
let dirsToWatch = fileIncludes.Includes |> Seq.map (fun file -> Globbing.getRoot fileIncludes.BaseDirectory file)

// remove subdirectories from watch list so that we don't get duplicate file watchers running
dirsToWatch
|> Seq.filter (fun d ->
dirsToWatch
|> Seq.exists (fun p -> d.StartsWith p && p <> d)
|> not)
|> Seq.toList

/// Watches the for changes in the matching files.
/// Returns an IDisposable which allows to dispose all FileSystemWatchers.
///
Expand All @@ -39,14 +50,8 @@ let private handleWatcherEvents (status : FileStatus) (onChange : FileChange ->
/// )
///
let WatchChanges (onChange : FileChange seq -> unit) (fileIncludes : FileIncludes) =
let dirsToWatch = fileIncludes.Includes |> Seq.map (fun file -> Globbing.getRoot fileIncludes.BaseDirectory file)

// remove subdirectories from watch list so that we don't get duplicate file watchers running
let dirsToWatch =
dirsToWatch |> Seq.filter (fun d ->
dirsToWatch
|> Seq.exists (fun p -> p.StartsWith d && p <> d)
|> not)
let dirsToWatch = fileIncludes |> calcDirsToWatch

tracefn "dirs to watch: %A" dirsToWatch

// we collect changes in a mutable ref cell and wait for a few milliseconds to
Expand Down Expand Up @@ -84,7 +89,7 @@ let WatchChanges (onChange : FileChange seq -> unit) (fileIncludes : FileInclude
(timer:System.Timers.Timer).Start() )

let watchers =
dirsToWatch |> List.ofSeq |> List.map (fun dir ->
dirsToWatch |> List.map (fun dir ->
tracefn "watching dir: %s" dir

let watcher = new FileSystemWatcher(FullName dir, "*.*")
Expand Down
35 changes: 35 additions & 0 deletions src/test/Test.FAKECore/ChangeWatcherSpecs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Linq;
using Fake;
using Machine.Specifications;
using Microsoft.FSharp.Collections;

namespace Test.FAKECore
{
public class when_calculating_directories_to_watch
{
It should_watch_multiple_directories =
() =>
{
var includes = ListModule.OfArray(new[] { @"test1\bin\*.dll", @"test2\bin\*.dll", });
var fileIncludes = new FileSystem.FileIncludes(@"C:\Project", includes, ListModule.Empty<string>());

var dirsToWatch = ChangeWatcher.calcDirsToWatch(fileIncludes);

dirsToWatch.Length.ShouldEqual(2);
dirsToWatch.ShouldContain(Fake.Globbing.normalizePath(@"C:\Project\test1\bin"));
dirsToWatch.ShouldContain(Fake.Globbing.normalizePath(@"C:\Project\test2\bin"));
};

It should_only_take_the_most_root_path_when_multiple_directories_share_a_root =
() =>
{
var includes = ListModule.OfArray(new[] { @"tests\**\test1\bin\*.dll", @"tests\test2\bin\*.dll", });
var fileIncludes = new FileSystem.FileIncludes(@"C:\Project", includes, ListModule.Empty<string>());

var dirsToWatch = ChangeWatcher.calcDirsToWatch(fileIncludes);

dirsToWatch.Length.ShouldEqual(1);
dirsToWatch.ShouldContain(Fake.Globbing.normalizePath(@"C:\Project\tests"));
};
}
}
1 change: 1 addition & 0 deletions src/test/Test.FAKECore/Test.FAKECore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblySpecs.cs" />
<Compile Include="ChangeWatcherSpecs.cs" />
<Compile Include="FSIHelperSpecs.cs" />
<Compile Include="CliSpecs.cs" />
<Compile Include="FileHandling\CopyFileSpecs.cs" />
Expand Down

0 comments on commit 70ec26f

Please sign in to comment.