Monday, July 12, 2021

 

Addendum:

This is a continuation of the article on NuGet packages. Their sources and resolutions.

The reference to having a single package source to eliminate source that have duplicate packages is enforceable by an organization to bolster the security and integrity of packages used to build the source code. The organizations can include a list of registries behind the feed that can be used to source packages both internal and external and enforcing that the developers use only one feed enables them to consolidate all requests through the controlled feed. This is a desirable pattern and one that alleviates concerns of uncontrolled packages from different sources and eventually polluting the source code asset of the organization.

The developers also have a lot of tools for this purpose. First, the NuGet executable allows listing of packages along with the source. The list command can be used to browse the packages in the remote folder.

Similarly, the local command can be used with the NuGet Executable to view all the local caches to which the packages were downloaded. This is a very useful mechanism for trial and error. A developer can choose to clear all the packages and reinitiate the download. This is useful to try with different package feed and sources and narrows down the problem space in half for troubleshooting package dependencies.

It is also possible to find out the dependency tree for the assemblies referenced via packages. Although this is not directly supported by the tool used to list the packages and their locations, it is easy to walk the dependencies iteratively until all the dependencies have been enumerated. Visited dependencies do not need to be traversed again.  The site MyGet.org allows these dependencies to be visualized with reference to their feed but when drawing the dependency tree for a project, neither the compiler nor the NuGet executable provides that option as opposed to those available for other languages.

A sample method that relies on built-in functions to eliminate dependencies already visited looks somewhat like this:

        static void OutputGraph(LocalPackageRepository repository, IEnumerable<IPackage> packages, int depth)

        {

            foreach (IPackage package in packages)

            {

                Console.WriteLine("{0}{1} v{2}", new string(' ', depth), package.Id, package.Version);

 

                IList<IPackage> dependentPackages = new List<IPackage>();

                foreach (var dependencySet in package.DependencySets)

                {

                    foreach (var dependency in dependencySet.Dependencies)

                    {

                        var dependentPackage = repository.FindPackage(dependency.Id, dependency.VersionSpec, true, true);

                        if (dependentPackage != null)

                        {

                            dependentPackages.Add(dependentPackage);

                        }

                    }      

                }

 

                OutputGraph(repository, dependentPackages, depth += 3);

            }

        }

 Courtesy: Stackoverflow.com

If the visited needs to be tracked by caller, then the code would follow the conventional depth-first search:

DFS ( V, E)
For each vertex v in V
       V.color=white
       V.d = nil
  Time = 0
 For each vertex v in V:
       If v.color == white:
              DFS-Visit (V, E)
    
 DFS-VISIT (V,E, u)
  time = time + 1
   u.d = time
   u.color = gray
   foreach  vertex v adjacent to u
        If v.color == white
           DFS-VISIT(V,E,v)
         Else
               If v.d  <= u.d < u.f <= v.f  throw back edge exception.
 u.color = black
time = time + 1
 u.f = time

No comments:

Post a Comment