Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Fix excluded files and folder deletion triggers #112

Merged
merged 1 commit into from
May 26, 2016
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
25 changes: 25 additions & 0 deletions src/Microsoft.DotNet.Watcher.Core/IncludeContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.ProjectModel.Files;

namespace Microsoft.DotNet.Watcher.Core
{
internal static class IncludeContextExtensions
{
public static IEnumerable<string> ResolveFiles(this IncludeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

return IncludeFilesResolver
.GetIncludeFiles(context, "/", diagnostics: null)
.Select(f => f.SourcePath);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.ProjectModel.Files;
using Microsoft.DotNet.ProjectModel.Graph;

namespace Microsoft.DotNet.Watcher.Core.Internal
Expand All @@ -15,15 +17,34 @@ public Project(ProjectModel.Project runtimeProject)
ProjectFile = runtimeProject.ProjectFilePath;
ProjectDirectory = runtimeProject.ProjectDirectory;

Files = runtimeProject.Files.SourceFiles.Concat(
runtimeProject.Files.ResourceFiles.Values.Concat(
runtimeProject.Files.PreprocessSourceFiles.Concat(
runtimeProject.Files.SharedFiles))).Concat(
new string[] { runtimeProject.ProjectFilePath })
.ToList();
var compilerOptions = runtimeProject.GetCompilerOptions(targetFramework: null, configurationName: null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you have files included/excluded per configuration/framework?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ajaybhargavb this is a question for you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compile and embed are part of buildOptions which can be framework/configuration specific. So yes the schema supports it. But I am not sure if it makes sense to include/exclude files for specific framework/configuration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are rare scenarios like that but I am not sure if we need to proactively address them now.


var filesToWatch = new List<string>() { runtimeProject.ProjectFilePath };
if (compilerOptions?.CompileInclude != null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if my reply was confusing before, I meant that compilerOptions will never be null.

{
filesToWatch.AddRange(compilerOptions.CompileInclude.ResolveFiles());
}
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be additive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my questions for @ajaybhargavb

{
filesToWatch.AddRange(runtimeProject.Files.SourceFiles);
}

if (compilerOptions?.EmbedInclude != null)
{
filesToWatch.AddRange(compilerOptions.EmbedInclude.ResolveFiles());
}
else
{
filesToWatch.AddRange(runtimeProject.Files.ResourceFiles.Values);
}

filesToWatch.AddRange(runtimeProject.Files.SharedFiles);
filesToWatch.AddRange(runtimeProject.Files.PreprocessSourceFiles);

Files = filesToWatch;

var projectLockJsonPath = Path.Combine(runtimeProject.ProjectDirectory, "project.lock.json");

if (File.Exists(projectLockJsonPath))
{
var lockFile = LockFileReader.Read(projectLockJsonPath, designTime: false);
Expand Down
4 changes: 4 additions & 0 deletions src/Microsoft.DotNet.Watcher.Core/Internal/ProjectWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ private void GetProjectFilesClosure(string projectFile, ISet<string> closure)
foreach (var file in project.Files)
{
closure.Add(file);

// We need to add the folder because folder deletions only trigger
// for the folder, not for the files inside it
closure.Add(Path.GetDirectoryName(file));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you checked if watching the folder causes any triggers to be fired for any changes to the files underneath it, including the excluded files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's a good point. Let me check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to work

}

foreach (var dependency in project.ProjectDependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ public void DeleteCompiledFile()
}
}

// Delete an entire folder
[Fact]
public void DeleteSourceFolder()
{
using (var scenario = new GlobbingAppScenario())
using (var wait = new WaitForFileToChange(scenario.StartedFile))
{
scenario.Start();

var folderToDelete = Path.Combine(scenario.TestAppFolder, "include");
Directory.Delete(folderToDelete, recursive: true);

wait.Wait(_defaultTimeout,
expectedToChange: true,
errorMessage: $"Process did not restart because {scenario.StartedFile} was not changed");
}
}

// Rename a file included in compilation
[Fact]
public void RenameCompiledFile()
Expand Down
18 changes: 10 additions & 8 deletions test/TestApps/GlobbingApp/project.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
"emitEntryPoint": true,
"compile": {
"include": [
"Program.cs",
"include/*.cs"
],
"exclude": [
"exclude/*"
]
}
},
"compile": [
"Program.cs",
"include/*.cs"
],
"exclude": [
"exclude/*"
],
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
Expand Down