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);
}
}
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