Circular reference detector and package.config ordering

I work with a large project with a lot of dependencies and recently we've moved to nuget to help manage the mess. It's been alright so far, but I've found one issue.

If you have packages a and b referenced by project c, and package b also references a the order they're referenced in packages.config matters. I haven't found this documented anywhere. It seems that nuget normally saves the order correctly, but once it didn't
and we got rather confused.

If you reference b before a, when a is visited the circular reference detector fires. If a is first it's all OK.

I have a prototype fix for this which uses quickgraph to create a dependency graph and detect cycles on that. I haven't checked performance yet though. I'm currently tidying this up.

I don't have the exact file to hand - it's in the office and I don't have a Windows development environment at home, but it was like this:

Project-Model 0.1.0.0

Project-ModelDBSpecific 0.1.0.0

The version numbers were like that for some test work, normally the numbers are actually set to the build number on the CI server.

Using nuget 1.7 the order was definitely important. The project had about 10 packages managed via Nuget with the model/modeldbspecific at the bottom. This resulted in a rather long error claiming that every package was in a cycle, but when I moved them to
the top it only output those two packages.

OK, I've finally had time to get back on to this, and have found the root cause.

In PackageWalker.cs if a dependency cannot be resolved but it is not set to skip dependency errors the function simply returns. This leaves the package currently being checked in the Processing state. If another package that hasn't been checked yet then
references the package that referenced the failed dependency NuGet incorrectly returns this as a cycle error.

I think in this case an exception should be thrown instead of simply continuing resolution. I suspect in most cases the current behaviour works, but with the Pack command it continues on, leading to the cycle errors.

I've made the change but it breaks some unit tests as some other walkers expect to get their own dependency walker that follows the current behaviour. If throwing an exception is considered correct I'll look at the other areas that fail and fix them.

I'm interested in working on this issue, for which http://nuget.codeplex.com/workitem/2965 has been opened.

(I've attached a test case to it)

However I'd like to get some feedback on the expected behavior: what should "nuget pack xx.csproj" do, when the packages listed in packages.config do not fulfill all dependencies (i.e. some dependencies of the listed packages are missing?)

(a) Should dependency detection fail (because it could be unreliable), and a error message be shown telling which dependencies are missing ?

what should happen when the same package is referenced in different projects ?

I suggest the following:

If the package reference version is different among the projects, then throw an error

If version constraints are defined, intersect the constraints, and throw an error if the intersection is empty

If target frameworks are different, throw an error

A package reference is NOT a "development dependency" except if it so in all projects which refer to it (the values are AND-ed together).

It it all seems reasonable I'll go ahead with the implementation.
I will probably add some code in VersionUtility to help with intersecting version constraints, as it would now be needed in several places (once for 'aggregating' references version constraints, once for 'aggregating' dependency version constraints).