Closed zdenek-jelinek closed 6 months ago
One solution could be to dynamically create/update a global.json, specially the version
and rollForward
members, to make sure to use the correct global editorconfig / analyzer-config per major version of SDK. Then make sure the dotnet command working dir is correctly set.
Thank you for getting back to me. Sorry for taking a bit to get back to you but the repro is not trivial.
To sum up, I think there is a misunderstanding - I am not looking to tie SDK version with my build, I am happy to run the latest SDK. I think the suggestion in the above comment is focused on stabilizing rulesets/behavior according to SDK version. While it is a related concept, it does not help with resolving the core issue.
What I have is a multi-target project (say .NET 6 + .NET 8) and I only want to run dotnet format
for specific target framework (e. g. .NET 8) because in the specific context (CI run), I am not interested in .NET 6 version. It may not even compile for the matter and that's fine. I'm building .NET 8 in this run.
To reproduce what I mean, follow these steps:
dotnet new console --language C# --name DotnetFormatExample --no-restore --framework net6.0 --use-program-main
Update the resulting csproj to contain additional target framework, e.g. .NET 8 (I don't know of any way of doing this via CLI)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Add a package reference under .NET 8 so that there is someting to restore Do this conditionally only for one TFM so that the restore for the other TFM fails (in this case, it will fail for .NET 6) I'd use CLI but the --framework switch there does not seem to work with SDK 8.0.100
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net8.0'">
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>
Use the package in code, e.g. Program.cs:
using Newtonsoft.Json;
namespace DotnetFormatExample;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(JsonConvert.SerializeObject(new { Greeting = "Hello, World!" }));
}
}
[*.cs]
dotnet_diagnostic.IDE0005.severity = warning
dotnet restore -p:TargetFramework=net8.0
dotnet build --framework net8.0 --no-restore
dotnet run --framework net8.0 --no-build
{"Greeting":"Hello, World!"}
dotnet format --verify-no-changes --no-restore --verbosity detailed
The format runs for both .NET 8 and .NET 6 and fails for the latter, specifying that the Newtonsoft.Json using in Program.cs is unnecessary. I will not reproduce the actual message as it is localized and I have so far found no way of turning that off.The suggestion in the comment above does not help with this:
{
"sdk": {
"version": "8.0.100"
}
}
dotnet --version
8.0.100
dotnet format --verify-no-changes --no-restore --verbosity detailed
A workaround I am not entirely happy about:
SET TargetFramework=net8.0
(or whatever is the syntax in your environment of choice)dotnet format --verify-no-changes --no-restore --verbosity detailed
Now this was a contrived example but with private artifact feed and more complex projects structure, this reproduces in identical fashion - format is run without preceding restore for some target and subsequently fails.
I am not too worried by the errors produced being misleading. My primary goal is to be able to specify that I want to only run dotnet format for a specific target framework. This can be reproduced without any conditional references and such as in the example above. It is enough to have a multi-targeted project, run dotnet format with detailed output and see that it considers all targets without any documented option of choice.
My bad, in this case the only way to avoid this kind of error while using multi-targeting with tied diff. per framework would be to use either preprocessor (code part) or conditional includes of files (csproj part). (in my knowledge)
No worries. Just to clarify, the main goal is to be able to avoid running format for .NET 6 at all even if it's in TargetFrameworks list. The error is just a place where it manifests in a way that explicitly needs a workaround.
Duplicate of #2057
📝 Note that #2057 is newer than this issue, but it's more direct feature request that's marked Help Wanted
I have an application with multiple target frameworks (TFMs). This serves as a step during migration to newer .NET. Each TFM is associated with a distinct set of package references, so that e.g. .NET 6 application binaries use Microsoft.Extensions. packages of version 6.0.x while .NET 7 application binaries use Microsoft.Extensions. packages of version 7.0.x.
When performing CI build, I have a pipeline linked with a specific target framework so that I have isolated artifacts and faster individual pipeline runs. Each such pipeline runs dotnet commands restricted to specific TFM using
--framework
parameter applicable to most dotnet-cli commands.However, when the pipeline gets to dotnet format, it fails with errors such as
IDE0005 Using directive is unneccessary
. Upon deeper investigation, I have found that this is caused by dotnet format running against all TFMs. In the described CI pipeline scenario, some of the target frameworks did not have their corresponding packages intentionally restored. Using statements refering to those packages are invalid and reported as unneccessary which causes the pipeline to fail.I have figured that I can work around this by using TagetFramework environment variable, although it feels quite hacky, especially since parametrization in the format
-p:Property=Value
does not seem to be supported either.Could you please add support for the ability to limit dotnet-format to specific target framework officially? E.g. via
--framework
option as used by other dotnet tooling.