Elskom / Sdk

Sdk to the elskom workload that helps with building plugins for Els_kom, Els_kom itself, and other applications as well.
MIT License
6 stars 5 forks source link

Regarding nuspec maintenance c/o @AraHaan #22

Closed StingyJack closed 3 years ago

StingyJack commented 3 years ago

as promised from https://github.com/NuGet/Home/issues/3891#issuecomment-761717868. We can move this elsewhere if needed (create an issue on any of my repos if you want to do that). I'm going to try to stick to the format of a list of suggestions and will number them for easier reference. The counts may not be perfectly accurate but should be representative of the order of magnitude.

1 - You have too many nuspec files. There only needs to be one, ideally for the release output. but you can make it work for debug or release by using $configuration$ in place of the Debug or Release folder path like this.

    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net40\GitBuildInfo.dll" target="tasks\net40\GitBuildInfo.dll" />

2 - In a nuspec file, there are too many dependency groups and targets. Currently there are 8 dependency groups with dependencies specified and 11 without dependencies specified. For the 11 netfx dependency groups, since there is no difference in dependencies. Since the only reason to declare a group for a later version is to indicate when dependencies change, you can really just specify the most base one (.NETFramework4.0) and it should work for all of them up to and including .NETFramework4.8.

Likewise for netcoreapp and netstandard, the dependencies specified are identical. you only need the .NETCoreApp2.0, and not all five .NETCoreApp's. I'm not entirely sure about net50's upgrade path in this respect, so I would leave that one as-is.

If you consolidate these entries into the four base groups (net40, netcore20, net50, netstandard20) you will go from 133 lines of <dependencies> to less than 50 lines.

Similarly for all the <file> target paths. Take the GitBuildInfo.dll - 19 lines when only 4 are needed.


 <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net40\GitBuildInfo.dll" target="tasks\net40\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net45\GitBuildInfo.dll" target="tasks\net45\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net451\GitBuildInfo.dll" target="tasks\net451\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net452\GitBuildInfo.dll" target="tasks\net452\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net46\GitBuildInfo.dll" target="tasks\net46\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net461\GitBuildInfo.dll" target="tasks\net461\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net462\GitBuildInfo.dll" target="tasks\net462\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net47\GitBuildInfo.dll" target="tasks\net47\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net471\GitBuildInfo.dll" target="tasks\net471\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net472\GitBuildInfo.dll" target="tasks\net472\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net48\GitBuildInfo.dll" target="tasks\net48\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\net5.0\GitBuildInfo.dll" target="tasks\net5.0\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netcoreapp2.0\GitBuildInfo.dll" target="tasks\netcoreapp2.0\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netcoreapp2.1\GitBuildInfo.dll" target="tasks\netcoreapp2.1\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netcoreapp2.2\GitBuildInfo.dll" target="tasks\netcoreapp2.2\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netcoreapp3.0\GitBuildInfo.dll" target="tasks\netcoreapp3.0\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netcoreapp3.1\GitBuildInfo.dll" target="tasks\netcoreapp3.1\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netstandard2.0\GitBuildInfo.dll" target="tasks\netstandard2.0\GitBuildInfo.dll" />
    <file src="..\GitBuildInfo\bin\Any CPU\$configuration$\netstandard2.1\GitBuildInfo.dll" target="tasks\netstandard2.1\GitBuildInfo.dll" />

If I do a bit of powershelling

PS Elskom.Sdk> $nuspec = [xml](Get-Content .\Elskom.Sdk.nuspec)
PS Elskom.Sdk> $allFileSources = $nuspec.package.files.file.src | Sort-Object

PS Elskom.Sdk> $projectOutputSources = $allFileSources | Where-Object {$_.EndsWith('.pdb') -or $_.EndsWith('.dll') -or $_.EndsWith('.xml')} | Sort-Object
PS Elskom.Sdk> $projectOutputSources.Count
1204  #this is the total number of <file> nodes for Dll's, PDB's, and XML's

PS Elskom.Sdk> $allLibs = $allFileSources | Where-Object {$_.EndsWith('.pdb') -or $_.EndsWith('.dll') -or $_.EndsWith('.xml')} | Foreach-Object {Split-Path $_ -Leaf} | Select-Object -Unique | Sort-Object
PS Elskom.Sdk> $allLibs.Count
40  #this is the number of distinct PDB, DLL, and XML src files

PS Elskom.Sdk> ($allLibs | Where-Object {$_.EndsWith('.dll')}).Count
14  #this is for adding in the /ref/ folder dll's and xml's that were deduplicated by the prior count

... there are only about 68 (40 + 14 ref dll + 14 ref xml ) unique project output file sources (not counting props files, etc). If the targets are made to match the dependency groups, you would go from 1204 lines to maintain to 272 (68 files * 4 dep groups). That can be further reduced by using wildcarding and collapsing this...

    <file src="..\MessageManager\bin\Any CPU\$configuration$\net40\MessageManager.dll" target="lib\net40\MessageManager.dll" />
    <file src="..\MessageManager\bin\Any CPU\$configuration$\net40\MessageManager.xml" target="lib\net40\MessageManager.xml" />
    <file src="..\MessageManager\bin\Any CPU\$configuration$\net40\MessageManager.pdb" target="lib\net40\MessageManager.pdb" />

... into this

    <file src="..\MessageManager\bin\Any CPU\$configuration$\net40\MessageManager.*" target="lib\net40" />

taking the lines to maintain down to about 16 (14 wildcard + 2 ref) per dependency group (~64 lines total). Also note the target can be a folder and does not need to be the full file name

Also, several of these older .net framework versions went out of support more than 5 years ago. Keeping them is up to you, just remember that keeping them is probably creating additional nuspec maintenance.

3 - We are programmers. We automate manual or tedious tasks for a living, yet sometimes we forget that. If any of this is not useful to you for any reason, or even if it is, I think you should write a script or program to fill out or create the nuspec on build and make it a pre-build action for the project you want to pack. The script can be fancy and dynamically determine project outputs using Roslyn, or you could keep it rudimentary and look for "$projectName.dll/pdb/xml" in each project folder. Powershell, csharp script (Scripty! lets you add tasks to a project file for running csharp scripts before/after build)

4 - Consider a metapackage for the least amount of maintenance. It would have no (or a few - *.props perhaps) files to refer, and would have dependencies of individual packages you could make for each project. Example here.

LMK if this was/ was not useful or if you have any questions.

AraHaan commented 3 years ago

@StingyJack for some reason on 5.0.102 on the .NET SDK on my build $configuration$ is either null or an empty string. I filed an issue here for it: https://github.com/dotnet/sdk/issues/15407

the one used -> Elskom.Sdk.nuspec.zip

StingyJack commented 3 years ago

is it only the .net5.0 stuff and all the other versions replace $configuration$ correctly?

I've had to specify the configuration explicitly before when running the nuget.exe pack command. Maybe try that and see if its able to force the issue.

If that doesnt work, definitely consider a script to at least do the $configuration$ string replacement prior to packing so you dont have to manually do it.

AraHaan commented 3 years ago

oh you use nuget pack, I basically feed the nuspec into an csproj too just for dotnet pack / pack while "build".

StingyJack commented 3 years ago

using nuget pack on the nuspec file is just to try to help isolate the problem or find a workaround since packing during build isnt working right for you.

AraHaan commented 3 years ago

@StingyJack so I tried it and the package then also gets packed with useless json files in these TFM's net5.0, net5.0-windows, netcoreapp2.0, netcoreapp2.1, netcoreapp2.2, netcoreapp3.0, netcoreapp3.1, netstandard2.0, netstandard2.1.

StingyJack commented 3 years ago

Which "useless json files"? The 'deps.json"?

AraHaan commented 3 years ago

Which "useless json files"? The 'deps.json"?

yes those.

AraHaan commented 3 years ago

Which "useless json files"? The 'deps.json"?

Also too bad I cant wildcard the TFM dirs too instead of hardcoding them in the nuspec.

AraHaan commented 3 years ago

Welp minified the TFM's and now not every thing is picked up despite having them be an lower TFM 😭.

Looks like the only way is to do the metapackage stuff.

AraHaan commented 3 years ago

Already done that and will need to test it locally too yet again.

AraHaan commented 3 years ago

Will reopen if I find issues.