Skip to content

Commit

Permalink
WIP Function to remove Compile elems missing files
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bentayloruk committed Jan 17, 2016
1 parent 492a157 commit 30832ea
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 2 deletions.
23 changes: 22 additions & 1 deletion src/app/FakeLib/MSBuild/ProjectSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module Fake.MSBuild.ProjectSystem

open Fake
open System
open System.Collections.Generic
open System.Xml
open System.Xml.Linq
Expand Down Expand Up @@ -159,4 +160,24 @@ let CompareProjectsTo templateProject projects =
|> toLines

if isNotNullOrEmpty errors then
failwith errors
failwith errors

let removeCompileNodesWithMissingFiles includeExistsF (project:ProjectFile) =
let projectDir = IO.Path.GetDirectoryName(project.ProjectFileName)
let missingFiles =
seq { for filePath in project.Files do
// We have to normalize the path, because csproj can have win style directory separator char on Mono too
// Xbuild handles them, so we do too http://www.mono-project.com/archived/porting_msbuild_projects_to_xbuild/#paths
let includePath = Globbing.normalizePath (IO.Path.Combine([|projectDir; filePath|]))
if not (includeExistsF(includePath)) then yield filePath }
missingFiles
|> Seq.fold (fun (project:ProjectFile) file -> project.RemoveFile(file)) project

/// Removes projects Compile nodes that have Include attributes pointing to files missing from the file system. Saves updated projects.
let RemoveCompileNodesWithMissingFiles project =
let newProject = removeCompileNodesWithMissingFiles System.IO.File.Exists (ProjectFile.FromFile project)
newProject.Save()




30 changes: 29 additions & 1 deletion src/test/Test.FAKECore/ProjectSystemSpecs.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Fake.MSBuild;
using System;
using System.Collections.Generic;
using System.IO;
using Fake.MSBuild;
using Machine.Specifications;

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

}

public class when_removing_compile_nodes_with_missing_files
{
const string ProjectFilePath = @"ProjectTestFiles/CSharpApp.csproj";
private static ProjectSystem.ProjectFile _project;

private Because of = () =>
{
Func<string, bool> fileExists = s =>
{
// We have to use Path.Combine here to work x-plat.
var pathsToRemove = new List<string>() {Path.Combine("ProjectTestFiles", "Class1.cs"), Path.Combine("ProjectTestFiles", "Folder", "FolderFile2.cs")};
return !pathsToRemove.Exists(pathToRemove => s.Equals(pathToRemove, StringComparison.InvariantCulture));
};
var projectFile = ProjectSystem.ProjectFile.FromFile(ProjectFilePath);
_project = ProjectSystem.removeCompileNodesWithMissingFiles(fileExists.Convert(), projectFile);
};

It should_delete_missing_files_in_csharpapp = () =>
{
_project.Files.ShouldNotContain(new []{"Class1.cs", @"Folder\FolderFile2.cs"});
// We DON'T have to use Path.Combine here, because the CsProj paths are same on both plats for our test proj.
_project.Files.ShouldContain(new [] {@"Folder\FolderFile1.cs", @"Program.cs", @"Properties\AssemblyInfo.cs"});
};
}
}
62 changes: 62 additions & 0 deletions src/test/Test.FAKECore/ProjectTestFiles/CSharpApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5C1A3730-057D-4C82-AF8B-32135611CB4B}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ConsoleApplication2</RootNamespace>
<AssemblyName>ConsoleApplication2</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Folder\FolderFile1.cs" />
<Compile Include="Folder\FolderFile2.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
3 changes: 3 additions & 0 deletions src/test/Test.FAKECore/Test.FAKECore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@
<Content Include="NAVFiles\Table_4.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ProjectTestFiles\CSharpApp.csproj">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="SideBySideSpecification\Project1.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
Expand Down

0 comments on commit 30832ea

Please sign in to comment.