Sunday, January 22, 2012

Adding the missing pieces to the Standalone StyleCop script

Rather than post the whole ~200 lines, just the salient bits so that the original can be tidied up (but without obscuring everything with obsessive error handling). Start by giving it parameters like

<#
.SYNOPSIS
Stand-alone stylecop runner.
.DESCRIPTION
Runs StyleCop over a project or a solution
.NOTES
File Name : Run-StyleCop.ps1
Requires : PowerShell Version 2.0
.PARAMETER FilesToScan
Project or Solution file
.PARAMETER StyleCopFolder
To override the heuristic looking in $env:ProgramFiles for the latest version
e.g. for StyleCop in source control
.PARAMETER OnlyBuildIntegrated
Only scan project files which include <Import Project="something with 'stylecop' in it" />
#>
param (
[Parameter(Mandatory = $true)] [string] $FilesToScan,
[string] $StyleCopFolder,
[switch] $OnlyBuildIntegrated)
Find StyleCop in the default install location by
if (-not $StyleCopFolder) {
$styleCopFolder = (dir "$($env:programFiles)*\stylecop*" | Sort-object LastWriteTimeUtc | Select-Object -Last 1).FullName
}
view raw gistfile1.ps1 hosted with ❤ by GitHub

Find StyleCop in the default install location by


if (-not $StyleCopFolder) {
    $styleCopFolder =  (dir "$($env:programFiles)*\stylecop*" | Sort-object LastWriteTimeUtc | Select-Object -Last 1).FullName
}

Get the list of projects by either just the project, or using a regex on the project file from here: http://bytes.com/topic/c-sharp/answers/483959-enumerate-projects-solution

if ($FilesToScan -like "*.csproj") {
$projectList = ,$FilesToScan
} else {
if ($FilesToScan -like "*.sln") {
$solutionDir = Split-Path $FilesToScan
$matchProjectNameRegex =
'^Project\("(?<PROJECTTYPEGUID>.*)"\)\s*=\s* "(?<PROJECTNAME>.*)"\s*,\s*"(?<PROJECTRELATIVEPATH>.*)"\s*,\s*"(?<PROJECTGUID>.*)"$'
# or we could filter on project guid being {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
$projectList = @(Get-Content $FilesToScan | % {
$matches = $null; $_ -match $matchProjectNameRegex | Out-Null; $matches.PROJECTRELATIVEPATH } | ? {
$_ -like "*.csproj" } | % { Join-Path $solutionDir $_ } )
} else {
Write-Error "$FilesToScan isn't a solution file or a C# project"
}
}
# Check if required for a StyleCop target
if ($OnlyBuildIntegrated) {
$projectList = @($projectList | ? {
[xml]$content = Get-Content $_
$imports = @($content.Project.Import)
$flagged = (@($imports | % { $_.Project } | ? { $_ -like "*stylecop*" })).Length
if ($flagged -eq 0) { Write-Host "Skipping project $_" }
($flagged -gt 0)
})}
view raw gistfile1.ps1 hosted with ❤ by GitHub

Find a Settings.StyleCop file by looking at the project folder and up, defaulting to one in the StyleCop folder; and then scan the C# files of interest by

[xml]$content = Get-Content $projectFile
# All C# files
$cs = @($content.Project.ItemGroup | % { $_.Compile } | ? {$_})
# Filter excluded files; get absolute paths
$projectDir = Split-Path $_
$cs = @($cs | ? { -not (($cs[0].ExcludeFromStyleCop -like "true") -or ($cs[0].ExcludeFromSourceAnalysis -like "true"))
} | % { Join-Path $projectDir $_.Include })
$cs | % { $console.Core.Environment.AddSourceCode($codeproject, $_, $null) | Out-Null }
view raw gistfile1.ps1 hosted with ❤ by GitHub

and customise the output file as

$name = (Split-Path $projectFile -Leaf).Replace(".csproj", ".StyleCop.xml")
$outputXml = Join-Path (Get-Location) $name
view raw gistfile1.ps1 hosted with ❤ by GitHub

No comments :