A real case - you want to play with a library, let's take Autofac. You create a folder named "autofac" then run dotnet new console
then dotnet add package Autofac
and then run VSCode anticipating a fun.
Agree to install required assets for .net project and run restore to get intellisense.
Bump! Error - NU1108: Cycle detected.
D:\Work\Learn\autofac>dotnet restore
Restoring packages for D:\Work\Learn\autofac\autofac.csproj...
D:\Work\Learn\autofac\autofac.csproj : error NU1108: Cycle detected.
D:\Work\Learn\autofac\autofac.csproj : error NU1108: autofac -> Autofac (>= 1.0.0).
Generating MSBuild file D:\Work\Learn\autofac\obj\autofac.csproj.nuget.g.props.
Restore failed in 247,83 ms for D:\Work\Learn\autofac\autofac.csproj.
then you have to renam autofac.csproj
to autofac-sandbox.csproj
and restore starts working but not VSCode. you'll have to recreate project. it pains.
D:\Work\Learn\autofac>dotnet restore
Restoring packages for D:\Work\Learn\autofac\autofac-sandbox.csproj...
Installing Autofac 2.2.4.900.
D:\Work\Learn\autofac\autofac-sandbox.csproj : warning NU1603: autofac-sandbox depends on Autofac (>= 1.0.0) but Autofac 1.0.0 was not found. An approximate best match of Autofac 2.2.4.900 was resolved.
This is by design.
Since project.json, NuGet has been moving towards project-package duality.
A project and a dependency cannot have the same name.
I don't think NuGet needs to do anything different here.
Another case is if you have an analyzer library and want to use the published analyzer on the analyzer code.
I tried <NoWarn>NU1108</NoWarn>
but it had no effect.
This is a general problem for toolset packages (DevelopmentDependency=true) that use previous versions of themselves during build. For example a Microsoft.SourceLink package.
I don't think NuGet needs to do anything different here.
I think NuGet needs to have a concept that allows it to distinguish between packages that are used in build and packages that are being built.
A workaround is to define PackageId to some unique value and then redefine it to the actual value in a target that runs just before Pack target.
<PropertyGroup>
<PackageId>*$(MSBuildProjectFullPath)*</PackageId>
</PropertyGroup>
<Target Name="_UpdatePackageId" BeforeTargets="$(PackDependsOn)" >
<PropertyGroup>
<PackageId>$(MSBuildProjectName)</PackageId>
</PropertyGroup>
</Target>
I think NuGet needs to have a concept that allows it to distinguish between packages that are used in build and packages that are being built.
I agree with this, it's just that other design decisions such as Dev dependency itself kind of limit/kill some of the options.
It'd be a significant undertaking, which we'd need to prioritize first.
// cc @rrelyea
Any progress on this issue? I ran into the same problem with a build package that is used by the project that builds the package.
I just hit this and I think it's a problem that needs addressing.
There are two ways to interpret a name when a project has the same name as a package. One of them results in a cycle, the other doesn't. How about trying both combinations and only failing when no self-consistent combinations are possible?
It is really unexpected honestly to try to interpret the name inside PackageReference as a project first. Shouldn't it try to interpret it as a package first, and only when that fails, fall back to projects?
And what does it even mean to have a PackageReference to a project? Shouldn't it then include a path to the .csproj and not just a name?
This is very strange and counter-intuitive design honestly.
@KirillOsenkov
I use the approach of @tmat as a workaround and put it into the Directory.Build.targets of my repository. It could also be moved into a build package:
<!--Begin: Avoid cycle error when package builds itself-->
<Choose>
<When Condition="$(AvoidCycleErrorOnSelfReference) == 'true'">
<PropertyGroup>
<PackageId Condition="'$(PackageId)' == ''">$(MSBuildProjectName)</PackageId>
<PackageIdTemp>$(PackageId)</PackageIdTemp>
<PackageId>$(PackageId)_temp</PackageId>
</PropertyGroup>
</When>
</Choose>
<Target Name="_UpdatePackageId" BeforeTargets="$(PackDependsOn)" Condition="$(AvoidCycleErrorOnSelfReference) == 'true'" >
<PropertyGroup>
<PackageId>$(PackageIdTemp)</PackageId>
</PropertyGroup>
</Target>
<!--End: Avoid cycle error when package builds itself-->
In a project where you run into the issue simply add:
<PropertyGroup>
<AvoidCycleErrorOnSelfReference>true</AvoidCycleErrorOnSelfReference>
</PropertyGroup>
Came across this today. Created my standalone (not a package) csproj called "Validation" several months ago. Today I tried to include "PInvoke.User32" - this has a dependency on a package called "Validation". How am I, as a developer, supposed to know that I should not have used "Validation" for my project name.
@KirillOsenkov @tmat I tried the workaround mentioned earlier and it seems to have worked. BUT I'm not building a package so why should defining a PackageId change anything for me?
Just ran into this problem. Hacked around it by renaming the project directory. At the very least, a useful error message would be appreciated.
just discovered that the workaround from here https://github.com/NuGet/Home/issues/6754#issuecomment-592283619 just works as long as your development package has no other development package as dependency, for which you have to avoid the cyclic dependency error as well.
If a dev package has a dependency on another dev package for which you workaround the cycle detection error you'd get the '_temp' package id as the dependency name in the referencing package.
Does anyone have a workaround for that scenario?
@nkolev92
Would it be difficult to add a flag that allows us to suppress the error? In case of dev package the error is a false positive, because if you add the dev package with 'PrivateAssets='all'' configured, it doesn't become a dependency of itself -> no cyclic dependency in that scenario
Most helpful comment
This is by design.
Since project.json, NuGet has been moving towards project-package duality.
A project and a dependency cannot have the same name.
I don't think NuGet needs to do anything different here.