Skip to content

Commit 30832ea

Browse files
committed
WIP Function to remove Compile elems missing files
As well as keeping project files in sync, I also need to be able to remove compile nodes from a project, where the Include attribute points to a file that is missing. This is useful when I have two projects including the same files, and I delete a bunch of them from the 'master' project I happen to be working on. This PR adds two functions. RemoveCompileNodesWithMissingFiles is intended for build script use and removeCompileNodesWithMissingFiles exists for testing purposes, because unlike the former, it does not write to the file system. I noticed this convention elsewhere in FAKE, but I'm not sure if it is considered idiomatic. Let me know.
1 parent 492a157 commit 30832ea

File tree

4 files changed

+116
-2
lines changed

4 files changed

+116
-2
lines changed

src/app/FakeLib/MSBuild/ProjectSystem.fs

+22-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
module Fake.MSBuild.ProjectSystem
33

44
open Fake
5+
open System
56
open System.Collections.Generic
67
open System.Xml
78
open System.Xml.Linq
@@ -159,4 +160,24 @@ let CompareProjectsTo templateProject projects =
159160
|> toLines
160161

161162
if isNotNullOrEmpty errors then
162-
failwith errors
163+
failwith errors
164+
165+
let removeCompileNodesWithMissingFiles includeExistsF (project:ProjectFile) =
166+
let projectDir = IO.Path.GetDirectoryName(project.ProjectFileName)
167+
let missingFiles =
168+
seq { for filePath in project.Files do
169+
// We have to normalize the path, because csproj can have win style directory separator char on Mono too
170+
// Xbuild handles them, so we do too http://www.mono-project.com/archived/porting_msbuild_projects_to_xbuild/#paths
171+
let includePath = Globbing.normalizePath (IO.Path.Combine([|projectDir; filePath|]))
172+
if not (includeExistsF(includePath)) then yield filePath }
173+
missingFiles
174+
|> Seq.fold (fun (project:ProjectFile) file -> project.RemoveFile(file)) project
175+
176+
/// Removes projects Compile nodes that have Include attributes pointing to files missing from the file system. Saves updated projects.
177+
let RemoveCompileNodesWithMissingFiles project =
178+
let newProject = removeCompileNodesWithMissingFiles System.IO.File.Exists (ProjectFile.FromFile project)
179+
newProject.Save()
180+
181+
182+
183+

src/test/Test.FAKECore/ProjectSystemSpecs.cs

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using Fake.MSBuild;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using Fake.MSBuild;
25
using Machine.Specifications;
36

47
namespace Test.FAKECore
@@ -76,4 +79,29 @@ public class when_removing_duplicate_files
7679
_project.FindDuplicateFiles().ShouldContain("Git\\CommitMessage.fs");
7780

7881
}
82+
83+
public class when_removing_compile_nodes_with_missing_files
84+
{
85+
const string ProjectFilePath = @"ProjectTestFiles/CSharpApp.csproj";
86+
private static ProjectSystem.ProjectFile _project;
87+
88+
private Because of = () =>
89+
{
90+
Func<string, bool> fileExists = s =>
91+
{
92+
// We have to use Path.Combine here to work x-plat.
93+
var pathsToRemove = new List<string>() {Path.Combine("ProjectTestFiles", "Class1.cs"), Path.Combine("ProjectTestFiles", "Folder", "FolderFile2.cs")};
94+
return !pathsToRemove.Exists(pathToRemove => s.Equals(pathToRemove, StringComparison.InvariantCulture));
95+
};
96+
var projectFile = ProjectSystem.ProjectFile.FromFile(ProjectFilePath);
97+
_project = ProjectSystem.removeCompileNodesWithMissingFiles(fileExists.Convert(), projectFile);
98+
};
99+
100+
It should_delete_missing_files_in_csharpapp = () =>
101+
{
102+
_project.Files.ShouldNotContain(new []{"Class1.cs", @"Folder\FolderFile2.cs"});
103+
// We DON'T have to use Path.Combine here, because the CsProj paths are same on both plats for our test proj.
104+
_project.Files.ShouldContain(new [] {@"Folder\FolderFile1.cs", @"Program.cs", @"Properties\AssemblyInfo.cs"});
105+
};
106+
}
79107
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{5C1A3730-057D-4C82-AF8B-32135611CB4B}</ProjectGuid>
8+
<OutputType>Exe</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>ConsoleApplication2</RootNamespace>
11+
<AssemblyName>ConsoleApplication2</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16+
<PlatformTarget>AnyCPU</PlatformTarget>
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<PlatformTarget>AnyCPU</PlatformTarget>
27+
<DebugType>pdbonly</DebugType>
28+
<Optimize>true</Optimize>
29+
<OutputPath>bin\Release\</OutputPath>
30+
<DefineConstants>TRACE</DefineConstants>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
</PropertyGroup>
34+
<ItemGroup>
35+
<Reference Include="System" />
36+
<Reference Include="System.Core" />
37+
<Reference Include="System.Xml.Linq" />
38+
<Reference Include="System.Data.DataSetExtensions" />
39+
<Reference Include="Microsoft.CSharp" />
40+
<Reference Include="System.Data" />
41+
<Reference Include="System.Net.Http" />
42+
<Reference Include="System.Xml" />
43+
</ItemGroup>
44+
<ItemGroup>
45+
<Compile Include="Class1.cs" />
46+
<Compile Include="Folder\FolderFile1.cs" />
47+
<Compile Include="Folder\FolderFile2.cs" />
48+
<Compile Include="Program.cs" />
49+
<Compile Include="Properties\AssemblyInfo.cs" />
50+
</ItemGroup>
51+
<ItemGroup>
52+
<None Include="App.config" />
53+
</ItemGroup>
54+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
55+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
56+
Other similar extension points exist, see Microsoft.Common.targets.
57+
<Target Name="BeforeBuild">
58+
</Target>
59+
<Target Name="AfterBuild">
60+
</Target>
61+
-->
62+
</Project>

src/test/Test.FAKECore/Test.FAKECore.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@
203203
<Content Include="NAVFiles\Table_4.txt">
204204
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
205205
</Content>
206+
<None Include="ProjectTestFiles\CSharpApp.csproj">
207+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
208+
</None>
206209
<Content Include="SideBySideSpecification\Project1.txt">
207210
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
208211
</Content>

0 commit comments

Comments
 (0)