From 90cf14666be987b6bab28eafec14b7a09ae4b654 Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Thu, 13 Aug 2015 19:51:09 +1000 Subject: [PATCH 1/4] Fixed WatchChanges function not properly calculating the most rooted directories to watch for changes when there are multiple paths on the same root --- src/app/FakeLib/ChangeWatcher.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/FakeLib/ChangeWatcher.fs b/src/app/FakeLib/ChangeWatcher.fs index 875b992f847..810c7bffed8 100644 --- a/src/app/FakeLib/ChangeWatcher.fs +++ b/src/app/FakeLib/ChangeWatcher.fs @@ -45,7 +45,7 @@ let WatchChanges (onChange : FileChange seq -> unit) (fileIncludes : FileInclude let dirsToWatch = dirsToWatch |> Seq.filter (fun d -> dirsToWatch - |> Seq.exists (fun p -> p.StartsWith d && p <> d) + |> Seq.exists (fun p -> d.StartsWith p && p <> d) |> not) tracefn "dirs to watch: %A" dirsToWatch From ac2fc12be4a459d309042bd45f2cdec64269ed9d Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Thu, 13 Aug 2015 21:23:33 +1000 Subject: [PATCH 2/4] Refactored ChangeWatcher code a little to make the watch directory calculation testable --- src/app/FakeLib/ChangeWatcher.fs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/app/FakeLib/ChangeWatcher.fs b/src/app/FakeLib/ChangeWatcher.fs index 810c7bffed8..594f4b3d8a8 100644 --- a/src/app/FakeLib/ChangeWatcher.fs +++ b/src/app/FakeLib/ChangeWatcher.fs @@ -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. /// @@ -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 -> d.StartsWith p && 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 @@ -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, "*.*") From ff5d3687892bdfb9c6580b56a89df9f1cb19d159 Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Thu, 13 Aug 2015 21:24:28 +1000 Subject: [PATCH 3/4] Added tests for the calcDirsToWatch function to ensure it properly determines duplicate root paths now --- src/test/Test.FAKECore/ChangeWatcherSpecs.cs | 34 ++++++++++++++++++++ src/test/Test.FAKECore/Test.FAKECore.csproj | 1 + 2 files changed, 35 insertions(+) create mode 100644 src/test/Test.FAKECore/ChangeWatcherSpecs.cs diff --git a/src/test/Test.FAKECore/ChangeWatcherSpecs.cs b/src/test/Test.FAKECore/ChangeWatcherSpecs.cs new file mode 100644 index 00000000000..c65b7bcb4cf --- /dev/null +++ b/src/test/Test.FAKECore/ChangeWatcherSpecs.cs @@ -0,0 +1,34 @@ +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()); + + var dirsToWatch = ChangeWatcher.calcDirsToWatch(fileIncludes); + + dirsToWatch.Length.ShouldEqual(2); + dirsToWatch.ShouldContain(@"C:\Project\test1\bin"); + dirsToWatch.ShouldContain(@"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()); + + var dirsToWatch = ChangeWatcher.calcDirsToWatch(fileIncludes); + + dirsToWatch.Length.ShouldEqual(1); + dirsToWatch.ShouldContain(@"C:\Project\tests"); + }; + } +} diff --git a/src/test/Test.FAKECore/Test.FAKECore.csproj b/src/test/Test.FAKECore/Test.FAKECore.csproj index a0ef4dc1457..164dc79736e 100644 --- a/src/test/Test.FAKECore/Test.FAKECore.csproj +++ b/src/test/Test.FAKECore/Test.FAKECore.csproj @@ -67,6 +67,7 @@ + From 02639493dd62ea25b55ba9c22f29190d86435f69 Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Thu, 13 Aug 2015 23:25:23 +1000 Subject: [PATCH 4/4] Normalised the paths in the tests so that they pass on *nix systems --- src/test/Test.FAKECore/ChangeWatcherSpecs.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/Test.FAKECore/ChangeWatcherSpecs.cs b/src/test/Test.FAKECore/ChangeWatcherSpecs.cs index c65b7bcb4cf..c26c7429085 100644 --- a/src/test/Test.FAKECore/ChangeWatcherSpecs.cs +++ b/src/test/Test.FAKECore/ChangeWatcherSpecs.cs @@ -1,4 +1,5 @@ -using Fake; +using System.Linq; +using Fake; using Machine.Specifications; using Microsoft.FSharp.Collections; @@ -15,8 +16,8 @@ public class when_calculating_directories_to_watch var dirsToWatch = ChangeWatcher.calcDirsToWatch(fileIncludes); dirsToWatch.Length.ShouldEqual(2); - dirsToWatch.ShouldContain(@"C:\Project\test1\bin"); - dirsToWatch.ShouldContain(@"C:\Project\test2\bin"); + 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 = @@ -28,7 +29,7 @@ public class when_calculating_directories_to_watch var dirsToWatch = ChangeWatcher.calcDirsToWatch(fileIncludes); dirsToWatch.Length.ShouldEqual(1); - dirsToWatch.ShouldContain(@"C:\Project\tests"); + dirsToWatch.ShouldContain(Fake.Globbing.normalizePath(@"C:\Project\tests")); }; } }