dotnet-affected icon indicating copy to clipboard operation
dotnet-affected copied to clipboard

Deleted file does not affect project

Open batkaevruslan opened this issue 1 year ago • 7 comments

I've noticed that if file deletion is the only change, dotnet-affected does not include the project in the list of affected.

File deletion can break compilation of the project, so it must be returned as affected.

Repro: I've created a test to show the issue (test fails):

        [Fact]
        public async Task When_file_is_deleted_from_project_project_should_have_changed()
        {
            // Create a project
            var projectName = "InventoryManagement";
            var msBuildProject = Repository.CreateCsProject(projectName);
            // Create a file with some changes
            var targetFilePath = Path.Combine(projectName, "file.cs");
            await this.Repository.CreateTextFileAsync(targetFilePath, "// Initial content");

            // Make a commit and keep track of the sha
            this._fromCommit = Repository.StageAndCommit()
                .Sha;

            this.Repository.DeleteFile(targetFilePath);
            // Commit the changes
            this._toCommit = Repository.StageAndCommit()
                .Sha;

            Assert.Single(AffectedSummary.ProjectsWithChangedFiles);
            Assert.Empty(AffectedSummary.AffectedProjects);

            var projectInfo = AffectedSummary.ProjectsWithChangedFiles.Single();
            Assert.Equal(projectName, projectInfo.GetProjectName());
            Assert.Equal(msBuildProject.FullPath, projectInfo.GetFullPath());
        }

batkaevruslan avatar Aug 20 '23 17:08 batkaevruslan

Interesting! thank you so much for reproducing with a test. I honestly though we already had this dialed in.

I will take a look as soon as I have the time, which unfortunately is on the low end right now.

Leo.

leonardochaia avatar Sep 25 '23 10:09 leonardochaia

Hey all! I've been taking a look at this and I've found the culprit, still don't know how we are gonna fix it but wanted to provide an update. This is happening since we introduced MSBuild Predictions to determine a project's inputs. It is not an MSBuild.Predictions bug, but it is in how we use it.

https://github.com/leonardochaia/dotnet-affected/blob/2de16bc0bf0995aeef0bb9aeb163b257bf89645e/src/DotnetAffected.Core/Prediction/PredictionChangedProjectsProvider.cs#L62-L91

You can see here how we use MSBuild.Predictions to determine which files belongs to which project. However, since the file is deleted, it is not predicted as a project input.

This wouldn't have been an issue with the old behavior before predictions, where we simply checked if the file path was a subpath of the project path, but references outside of the project's directory were ignored..

Not sure what the fix is yet.. but that is why it is broken.

leonardochaia avatar Jan 14 '24 12:01 leonardochaia

Not sure what the fix is yet.. but that is why it is broken

Yeah I just took a crack at this too. I guess one option is to walk all the commits here and get a list of all files ever being in that project across the commit range; that should detect files being removed at least. But that might have other bad side effects.

tanordheim avatar Jan 15 '24 09:01 tanordheim

Hi @tanordheim , deleted files are already being discovered by git diff, however, we fail to map them to a project due to the project not having the deleted file predicted as an input. I think doing the path contains thing may be enough for now, at least as a workaround.

leonardochaia avatar Jan 15 '24 11:01 leonardochaia

Hi @tanordheim , deleted files are already being discovered by git diff, however, we fail to map them to a project due to the project not having the deleted file predicted as an input. I think doing the path contains thing may be enough for now, at least as a workaround.

Yeah, what I meant is if we walk all the commits to detect any files that have been present in the project at any given time we would then find a project that referenced the deleted file in one of the commits before the file was deleted and pick up on the affected project that way.

Your way sounds simpler to implement though, maybe its the way to go. I guess that leaves a bug where deleted files in a project that was referenced outside of the project root will not cause the project to be affected. As far as I understand, the reason for using MSBuild Predictions is to cover cases where files are referenced outside the project root. That is still a fairly minor thing I guess, I have no use cases like that personally.

tanordheim avatar Jan 15 '24 11:01 tanordheim

guess that leaves a bug where deleted files in a project that was referenced outside of the project root will not cause the project to be affected.

That is correct yep. I think it is hard to fix it in a performant way. Still need to think about it.

v4 will get released today with net8 support and we'll leave this one for a feature release soon.

leonardochaia avatar Jan 15 '24 11:01 leonardochaia