fsprojects / Paket

A dependency manager for .NET with support for NuGet packages and Git repositories.

Home Page:https://fsprojects.github.io/Paket/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Circular Project Reference Error

nicholi opened this issue · comments

Description

Rather obtuse StackTrace from simple circular dependency mistake. Hard to understand what the problem is from the Exception alone.

Repro steps

Command instructions to run on both Windows (powershell) and Linux (bash) to create dummy projects.

mkdir TestSln
cd TestSln

# empty sln and csproj's
dotnet new sln
dotnet new classlib -n TestProject1
dotnet new classlib -n TestProject2

# add projects to sln
dotnet sln add TestProject1
dotnet sln add TestProject2

# paket init
dotnet new tool-manifest
dotnet tool install paket
dotnet paket init

# adding single dependency for paket to manage
echo "nuget System.Text.Json" >> paket.dependencies
echo "System.Text.Json" > TestProject1/paket.references
echo "System.Text.Json" > TestProject2/paket.references

# now add circular reference between projects
dotnet add TestProject1 reference TestProject2
dotnet add TestProject2 reference TestProject1

# receive enormous error
dotnet paket install

Abbreviated beginning and end of response. Approximately 12k lines in total.

Paket version 8.0.3+75b30cdcb8859e8d129f139444d9b9b600bfff07
Skipping resolver for group Main since it is already up-to-date
Installing into projects:
Created dependency graph (9 packages in total)
Stack overflow.
   at System.String.op_Equality(System.String, System.String)
   at MS.Internal.Xml.XPath.XPathParser.get_IsNodeType()
   at MS.Internal.Xml.XPath.XPathParser.get_IsPrimaryExpr()
   at MS.Internal.Xml.XPath.XPathParser.ParsePathExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseUnionExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseUnaryExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseMultiplicativeExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseAdditiveExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseRelationalExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseEqualityExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseAndExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseOrExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseExpression(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParsePredicate(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseStep(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseRelativeLocationPath(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseLocationPath(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParsePathExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseUnionExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseUnaryExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseMultiplicativeExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseAdditiveExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseRelationalExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseEqualityExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseAndExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseOrExpr(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseExpression(MS.Internal.Xml.XPath.AstNode)
   at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpression(System.String)
   at System.Xml.XPath.XPathExpression.Compile(System.String, System.Xml.IXmlNamespaceResolver)
   at System.Xml.XPath.XPathNavigator.Select(System.String)
   at System.Xml.XmlNode.SelectSingleNode(System.String)
   at Paket.ProjectFileModule.forceGetName@1346(System.Xml.XmlNode, System.String)
   at Paket.ProjectFileModule.makePathNode@1377(Paket.ProjectFile, System.Xml.XmlNode, Boolean, System.String)
   at Paket.ProjectFileModule.getInterProjectDependencies(Paket.ProjectFile)
   at Paket.InstallProcess.dependencies@234-9[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](GroupName, Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<GroupName,PackageName,System.String>,System.__Canon>, System.Collections.Generic.Dictionary`2<System.String,Microsoft.FSharp.Core.FSharpOption`1<Paket.ProjectFile>>, System.Collections.Generic.Dictionary`2<Paket.ProjectFile,Microsoft.FSharp.Collections.FSharpSet`1<System.Tuple`2<PackageName,Paket.TargetProfile>>>, System.Collections.Generic.Dictionary`2<Paket.ProjectFile,Microsoft.FSharp.Core.FSharpOption`1<Paket.ReferencesFile>>, Paket.ProjectFile)
...
... skipping middle
...
   at Paket.InstallProcess.InstallIntoProjects[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Paket.InstallerOptions, Boolean, Paket.DependenciesFile, Paket.LockFile, Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`2<Paket.ProjectFile,Paket.ReferencesFile>>, Microsoft.FSharp.Collections.FSharpMap`2<GroupName,System.__Canon>, Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`4<GroupName,PackageName,Microsoft.FSharp.Core.FSharpOption`1<Paket.SemVerInfo>,Microsoft.FSharp.Core.FSharpOption`1<Paket.SemVerInfo>>>>)
   at Paket.UpdateProcess.SmartInstall(Paket.DependenciesFile, UpdateMode, Paket.UpdaterOptions)
   at <StartupCode$Paket-Core>.$PublicAPI+Install@269.Invoke(Microsoft.FSharp.Core.Unit)
   at Paket.Utils.RunInLockedAccessMode(System.String, Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Boolean>)
   at Paket.Dependencies.Install(Paket.InstallerOptions)
   at Paket.Dependencies.Install(Boolean, Boolean, Boolean, Boolean, Boolean, Paket.SemVerUpdateMode, Boolean, Boolean, Microsoft.FSharp.Collections.FSharpList`1<System.String>, Microsoft.FSharp.Collections.FSharpList`1<System.String>, Microsoft.FSharp.Core.FSharpOption`1<System.String>)
   at Paket.Program+main@957-11.Invoke(Microsoft.FSharp.Core.Unit)
   at Paket.Program.processWithValidationEx[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Microsoft.FSharp.Core.Unit>, Boolean, Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Microsoft.FSharp.Core.Unit>, System.__Canon)
   at Paket.Program.main()
   at <StartupCode$paket>.$Paket.Program.main@()

Expected behavior

Would it be possible for paket to discover such a circular reference before it crashes like this? And print something slightly more meaninful?

Otherwise this isn't really a bug, more a feature enhancement ask.

Attempting an actual build helps reveal the underlying issue.

PS > dotnet build
MSBuild version 17.9.8+b34f75857 for .NET
  Determining projects to restore...
C:\Program Files\dotnet\sdk\8.0.204\NuGet.targets(1194,5): error MSB4006: There is a circular dependency in the target dependency graph involving target "_GenerateRestoreProjectPathWalk". [D:\dolby\TestSln\Te
stProject2\TestProject2.csproj]

Build FAILED.