DependenSee icon indicating copy to clipboard operation
DependenSee copied to clipboard

Duplicate nodes for relative project reference

Open paul-hammant opened this issue 2 years ago • 22 comments

To reproduce: generate a HTML DependenSee for https://github.com/devpro/withywoods

image

^ not sure why nodes are duplicated like above.

paul-hammant avatar May 30 '22 06:05 paul-hammant

Hey thanks for the report. I'll have a look and get back.

madushans avatar May 30 '22 12:05 madushans

I ran DependenSee over the withywoods project, but could not reproduce the issue mentioned.

From your screenshot you may have run it from a different folder that I did.

My steps are below

  • navigate to https://github.com/devpro/withywoods
  • download ZIP
  • extract the zip file
  • open cmd on to extracted folder (C:\Users\Madushan\Downloads\withywoods-master)
  • run dependensee . test.html

My cmd prompt was C:\Users\Madushan\Downloads\withywoods-master>dependensee . test.html

My output is below.

I'm interested in what's different from how you did it. May be you ran it from a subfolder which made the relative paths in one or more projects in the csproj resolve differently? If this is the case I can look into adding a bugfix or a warning to the output.

image

madushans avatar May 30 '22 23:05 madushans

Latest version (2.2.0) now emits a warning into stderr if it detects there are project references outside of the specified SourceFolder

https://github.com/madushans/DependenSee/releases/tag/2.2.0

madushans avatar Jun 18 '22 06:06 madushans

This same issue is occurring in my solution as well, I had to use your tool in a script to run it per project within my solution directory and write an html file per project as output to make sense of it. Here's a screenshot. I'm happy to help you repro this if you'd be interested in reopening the ticket.

In our case I have a structure like this:

base folder
|- Project.1
  |- Project.1.csproj
|- Project.2
  |- Project.2.csproj
|- ...
|- Project.X
  |- Project.X.csproj
|- Something.sln

All of the project folders contain csproj files, that reference the other projects via ../Project.Whatever/Project.Whatever.csproj style references.

Here's an example of just some of the dupes in my output that aren't being collapsed.
This happens both if I run dependenSee from the root with . as the input folder, or with the full path to my root folder:

image

jeremy-allocate avatar Feb 24 '23 15:02 jeremy-allocate

can you confirm you ran the tool on the base folder? and if there were any warnings during the run?

Is it possible to get a sample folder (needs just the folder structure and csproj files) that can reproduce the issue?

madushans avatar Feb 25 '23 01:02 madushans

I can't share our source folder unfortunately (proprietary, etc), but I can try to create a sample repro case in a new repo for you.

But yes, I was cd'd into the root (/full/path/to/root/ in the examples below) folder at the terminal, and ran it with both

DependenSee -S . -O ./output/everything.html

and

DependenSee -S /full/path/to/root/ -O /full/path/to/root/output/everything.html

and got the same result both ways.

I don't see any warnings at the console during the run, just one line of output saying the file was written.

jeremy-allocate avatar Feb 25 '23 02:02 jeremy-allocate

Actually, perhaps I'll try to repro with the sample repo in the OP's original post first.

jeremy-allocate avatar Feb 25 '23 02:02 jeremy-allocate

Yes, I can repro with his code. I checked it out, cd'd into the directory, and executed

DependenSee -S . -O output/test.html

image

jeremy-allocate avatar Feb 25 '23 02:02 jeremy-allocate

I also just tried the following to see if the same would happen when the html was not written to a subfolder of the root, but directly to the root instead. Got the same result with dupes.

DependenSee -S . -O test.html

I'm on dotnet 6, running this in Debian under WSL2 on Windows, in case it somehow matters.

I installed via dotnet tool install DependenSee --global

image

jeremy-allocate avatar Feb 25 '23 03:02 jeremy-allocate

This zip has the resulting test.html file, thought it might help test.zip

jeremy-allocate avatar Feb 25 '23 03:02 jeremy-allocate

Thank you. It looks like the issue is the path separator being different on linux.

Either there's some assumption in DependenSee that the separator is \ which is likely, and/or your csproj files have \ as the separator, but all the file APIs return / in the paths. So the discovery doesn't see them as the same project file.

DependenSee uses Path.GetRelativePath which I thought would handle this on linux, but it evidently doesn't.

Thanks for your help. I'll look into adding a fix to normalize them and update here.

image

madushans avatar Feb 25 '23 03:02 madushans

Awesome, glad I could help track it down :)

jeremy-allocate avatar Feb 25 '23 16:02 jeremy-allocate

Hi @madushans - I have a fix for this that I'd like to create a PR for, could you grant me access to do that please?

It involves adding this small snippet after line 196 of ReferenceDiscoveryService.cs where referencePath is declared (in DiscoverProjectReferences()):

        if (!string.IsNullOrEmpty(referencePath))
        {
            // dotnet csproj files use the windows file separator character on all platforms, even linux.  Replace with the local system's character(s) so the full path can actually be calculated.
            referencePath = referencePath.Replace("\\", Path.DirectorySeparatorChar.ToString());
        }

I ran it on the same demo repo from vscode after making the change, and it produces a nice clear graph of the dependency structure in OP's original repo about to try it on my own code:

image

Edit: confirmed, it fixes the output on my solution too!!

jeremy-allocate avatar Jul 23 '23 20:07 jeremy-allocate

Awesome thank you @jeremy-allocate You can put a PR against the dev branch. Shouldn't need any special access.

madushans avatar Jul 24 '23 12:07 madushans

Strange, I couldn't push up a new branch to then PR against dev when I tried yesterday. Is a different process required?

Oh, apparently a fork based workflow is common? I'll try that.

jeremy-allocate avatar Jul 24 '23 14:07 jeremy-allocate

That worked: https://github.com/madushans/DependenSee/pull/36/files

Edit: actually I accidentally made this one against main - would you prefer it refiled against dev?

jeremy-allocate avatar Jul 24 '23 21:07 jeremy-allocate

Hey sorry forgot about this. Yea please base on dev.

Want to keep tip of main lined up with latest released version as much as possible in case we have to hot patch anything.

madushans avatar Jul 29 '23 08:07 madushans

Makes sense, all fixed! https://github.com/madushans/DependenSee/pull/37

jeremy-allocate avatar Jul 30 '23 01:07 jeremy-allocate

Thanks. Will leave this open until https://github.com/madushans/DependenSee/pull/37 gets released.

madushans avatar Jul 30 '23 02:07 madushans

Lol. I was ready to report about my duplication issue when I found the cause.

What I was observing is that one of the projects is added twice, with all of its dependencies.

Screenshot of a subgraph with aligned copies:

image

  • bottom left - a copy that is added properly and integrated into the rest of the graph,
  • bottom right - a copy that is unnecessary, along with all its dependencies.

What helped to figure out what happens here is generating output in a different format and see how duplicated nodes look there.

dependensee . .\graph.json -T json

Got me this:

//...
{
  "Id": "\\MigrationBackup\\be8e6ab6\\Project1\\Project1.csproj",
  "Name": "Project1"
},
{
  "Id": "\\Project1\\Project1.csproj",
  "Name": "Project1"
},
//...

Perhaps, if HTML output included tooltips with ids - it could've saved me some time to figure this. Extra nice if it could've automatically shown extra information inside otherwise synonymous nodes (same as what happens when opening same-named files in vscode).

KillyMXI avatar Oct 19 '23 00:10 KillyMXI

Few questions to narrow this down.

  1. do those 2 projects in the output are the exact same file? or are there 2 files? (One says MigrationBackup, wondering you have a copy there that DependenSee picked out)
  2. If they're the same file, can you find if there are 2 projects refer to this same project with different paths? You can do this by opening the solution folder in VS Code (not Visual Studio) and searching for Project1.csproj. You will likely get multiple matches anyway. But I'm interested in if there are 2 sets of projects that refer to this Project1.csproj with 2 canonical paths.

This is just for future reference. I think both these cases should be fixed in #37. This is more instances than I hoped people would run into this case. So I'll do a release to fix this one.

As for showing extra info, this is a bit hard in the current setup. The visualization library vis.js does have the flexibility, but it's not like we can put some <div> s in there. We have to draw into a canvas and do some pixel measurements .etc. to make it nice, so I've been delaying this work for a while 🙃 since I've been thinking of swapping it out for something that gives a bit more higher level API for this. But I haven't been able to find a good one that matches.

madushans avatar Oct 19 '23 03:10 madushans

From .gitignore:

# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/

\\MigrationBackup\\be8e6ab6\\ simply contained a copy of one project folder before using Package Reference Convert tool. (It is a .Net Framework project, and I only recently converted it further to new csproj format.)

Looks like DependenSee simply found all csproj files. I deleted the backup to resolve the duplication issue.

If you can, taking .gitignore into account is probably a good idea. Or allow to point at the solution file and only include projects from it.

KillyMXI avatar Oct 19 '23 08:10 KillyMXI