We are working on several ASP.NET MVC C# projects within Visual Studio 2015 and Team Foundation Server 2013. Sometimes the NuGet upgrade process is a mess and some of the replaced files (mostly *.png, *.gif, *.ttf) have not been checked-in properly. What we have figured out so far: the check-in process gets into trouble, if directories should be removed and created in one step. You have to check-in twice. The problem is, if you don’t know about this and one of our developers retrieves the latest source, there are missing files. Visual Studio indicates that with a warning icon in Solution Explorer.
My question is: Is it possible to validate, if every file is present during gated-checkin or nightly-build on TFS which is linked in the csproj file? At least there should be a warning during build.
Hint: This is only a problem with files, which are not compiled (*.cs files) or do not have the setting “copy during build into output directory”. This happens e.g. with JS-files, which are bundled.
Final solution:
Write-Host "Check availability for all referenced files in all projects ..."
function Check-Files($directory, $files){
if (!$directory.EndsWith("/")) { $directory = "$($directory)/" }
ForEach($file in $files){
if($file){
Write-Host " Referenced file $($directory)$file"
if(-not (Test-Path "$($directory)$($file)")){
throw [System.IO.FileNotFoundException] "$($directory)$($file) not found."
}
}
}
}
function CheckProjectFile($csprojFile){
[xml]$projectContent = Get-Content $csprojFile
Write-Host "Checking project: $($csprojFile) ..."
$directory = Split-Path $csprojFile
ForEach($itemGroup in $projectContent.Project.ItemGroup){
Check-Files -files $itemGroup.Reference.HintPath -dir $directory
Check-Files -files $itemGroup.Compile.Include -dir $directory
Check-Files -files $itemGroup.None.Include -dir $directory
Check-Files -files $itemGroup.Content.Include -dir $directory
Check-Files -files $itemGroup.TypeScriptCompile.Include -dir $directory
Check-Files -files $itemGroup.ProjectReference.Include -dir $directory
}
}
$csprojFiles = Get-ChildItem -Path ./ -Recurse *.csproj | Select-Object -Property FullName
ForEach($file in $csprojFiles){
CheckProjectFile($file.FullName)
}
I added the script file to my Team Project on TFS, changed my build definition, added the script directory to my "Source Settings" and included the script into "Pre-build script path". Done!
I created a small piece of powershell that you can execute as a step before building the solution.
function Check-Files($files){
ForEach($file in $files){
if($file){
Write-Host "looking for $file"
if(-not (Test-Path $file)){
throw [System.IO.FileNotFoundException] "$file not found."
}
}
}
}
[xml]$projectContent = Get-Content ./your.csproj
ForEach($itemGroup in $projectContent.Project.ItemGroup){
Check-Files -files $itemGroup.Reference.HintPath
Check-Files -files $itemGroup.Compile.Include
Check-Files -files $itemGroup.None.Include
Check-Files -files $itemGroup.Content.Include
Check-Files -files $itemGroup.TypeScriptCompile.Include
Check-Files -files $itemGroup.ProjectReference.Include
}
Hope this helps you. Kind regards Jan