.csproj
in directory and subdirectories of D:\repos\M\Test
[1] PS D:\repos\M\Test> ls -r -filter "*.csproj" | select Directory, Name
Sample output
Directory Name
--------- ----
D:\repos\M\Test\M.Common M.Common.csproj
D:\repos\M\Test\M.Mocks M.Mocks.csproj
D:\repos\M\Test\M.StateMachines M.StateMachines.csproj
<ProjectReference\s*Include="([^"]+)"
in directory and subdirectory[2] PS D:\repos\M\Test> ls | sls '<ProjectReference\s*Include="([^"]+)"' | ForEach-Object {New-Object PSObject -Property @{Project=$_.Filename; DirectDep=$_.Matches.Groups[1].Value}}
Sample output
Project DirectDeps
------- ----------
dirs.proj D:\repos\M\Test\M.Common
dirs.proj D:\repos\M\Test\M.Mocks.csproj
dirs.proj D:\repos\M\Test\M.StateMachines.csproj
M.Common.csproj D:\repos\S\Common\Common.csproj
M.Common.csproj D:\repos\Q\Contracts\Contracts.csproj
M.Mocks.csproj D:\repos\S\Controller\Controller.csproj
M.StateMachines.csproj D:\repos\M\Common\Common.csproj
M.StateMachines.csproj D:\repos\T\Auth\Auth.csproj
Q1: How can I feed the output of [1] to [2] to limit [2]'s search to .csproj
files (i.e. exclude dirs.proj
) to get the following output
Project DirectDeps
------- ----------
M.Common.csproj D:\repos\S\Common\Common.csproj
M.Common.csproj D:\repos\Q\Contracts\Contracts.csproj
M.Mocks.csproj D:\repos\S\Controller\Controller.csproj
M.StateMachines.csproj D:\repos\M\Common\Common.csproj
M.StateMachines.csproj D:\repos\T\Auth\Auth.csproj
Q2: And then how can I take output of [2] and make it group by Project/Filename? To get the following output (or similar)
M.Common.csproj, D:\repos\S\Common\Common.csproj, D:\repos\Q\Contracts\Contracts.csproj
M.Mocks.csproj, D:\repos\S\Controller\Controller.csproj
M.StateMachines.csproj, D:\repos\M\Common\Common.csproj, D:\repos\T\Auth\Auth.csproj
Attempts @ Q1
ls -r -filter "*.csproj" | ForEach-Object {"$_.Directory\$_.Name"}
ls -r -filter "*.csrpoj" | select Path
ls -r -filter "*.csproj" | [2]
Attempts @ Q2
ls | sls '<ProjectReference\s*Include="([^"]+)"' | ForEach-Object {New-Object PSObject -Property @{Project=$_.Filename; DirectDep=$_.Matches.Groups[1].Value}} | group Project
ls | sls '<ProjectReference\s*Include="([^"]+)"' | ForEach-Object {New-Object PSObject -Property @{Project=$_.Filename; DirectDep=$_.Matches.Groups[1].Value}} | group Project | select Name, Group
ls | sls '<ProjectReference\s*Include="([^"]+)"' | ForEach-Object {New-Object PSObject -Property @{Project=$_.Filename; DirectDep=$_.Matches.Groups[1].Value}} | group Project | select Name, Group.DirectDep
The second of the 3 has the closest output to what I'm looking for
Name Group
---- -----
dirs.proj {@{Project=dirs.proj; DirectDep=...M.Common.csproj}, {Project=dirs.proj; DirectDep=...M.Mocks.csproj}, {Project=dirs.proj; DirectDep=...M.StateMachines.csproj}
M.Common.csproj {@{Project=M.Common.csproj; DirectDep=...Common.csproj}, {Project=M.Common.csproj; DirectDep=...Contracts.csproj}}
M.Mocks.csproj {@{Project=M.Mocks.csproj; DirectDep=...Controller.csproj}
M.StateMachines.csproj {@{Project=M.StateMachines.csproj; DirectDep=...Common.csproj}, {Project=M.StateMachines.csproj; DirectDep=...Auth.csproj}}
So assuming you do have the .NET SDK installed, you can simply use dotnet list reference
command to get all reference projects.
The code would be something like:
Get-ChildItem -Recurse -Filter *.csproj | ForEach-Object {
$references = dotnet list $_.FullName reference
if ($references.Count -gt 2) {
# When there are references found the first 2 lines will be:
# Project reference(s)
# --------------------
# you can choose to skip them here if you want to or just remove this condition
$references = $references | Select-Object -Skip 2
}
[pscustomobject]@{
ProjectName = $_.BaseName
ProjectPath = $_.FullName
PackageReferences = $references
}
}
As for the previous question, "how to exclude for example, dirs.proj
", if you use -Filter *.csproj
it shouldn't list it at all but for the sake of answering, you can use -Exclude
:
Get-ChildItem -Recurse -Filter *.csproj -Exclude dirs.proj |
ForEach-Object { .... } # same code shown above
Or Where-Object
:
Get-ChildItem -Recurse -Filter *.csproj |
Where-Object Name -NE dirs.proj |
ForEach-Object { .... } # same code shown above