Пример #1
0
        /// <summary>
        /// Returns a dictionary mapping of IPackages to their included files.
        /// </summary>
        /// <param name="package"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private IEnumerable <IPackage> GetDependencyAssemblyList(IPackage package, PackageAuditResult result)
        {
            var packageDependencies = new List <IPackage>();

            foreach (var dependency in package.Dependencies)
            {
                //HACK Slow and wrong and evil and I HATE ODATA.
                var dependencyPackage = _feedPackages.FirstOrDefault(p => p.Id.Equals(dependency.Id, StringComparison.OrdinalIgnoreCase));
                if (dependencyPackage == null)
                {
                    result.UnresolvedDependencies.Add(dependency);
                    continue;
                }
                packageDependencies.Add(dependencyPackage);
            }
            return(packageDependencies);
        }
Пример #2
0
        /// <summary>
        /// Audits a feed and provides back a set of results
        /// </summary>
        /// <returns></returns>
        public List <PackageAuditResult> Audit(IPackage packageToAudit = null)
        {
            StartPackageListDownload(this, new EventArgs());
            _feedPackages = _packageRepository.GetPackages().Where(p => p.IsLatestVersion).OrderBy(p => p.Id).ToList();
            FinishedPackageListDownload(this, new EventArgs());

            //If we are auditing the whole feed, use the whole feed as the audit package list.....
            _auditPackages = packageToAudit == null ? _feedPackages : new List <IPackage>(new[] { packageToAudit });

            foreach (var package in _auditPackages)
            {
                //OData wont let us query this remotely (again, f**k OData).
                if (_unlisted == false && package.Listed == false)
                {
                    continue;
                }

                StartPackageAudit(this, new PackageAuditEventArgs {
                    Package = package
                });

                //Try the next one if we are using this one as an exception
                if (_wildcards.Any(w => w.IsMatch(package.Id.ToLowerInvariant())))
                {
                    PackageIgnored(this, new PackageIgnoreEventArgs {
                        IgnoredPackage = package, Wildcard = true
                    });
                    continue;
                }
                if (_exceptions.Any(e => e.Equals(package.Id, StringComparison.OrdinalIgnoreCase)))
                {
                    PackageIgnored(this, new PackageIgnoreEventArgs {
                        IgnoredPackage = package, StringMatch = true
                    });
                    continue;
                }

                var currentResult = new PackageAuditResult {
                    Package = package
                };
                var actualAssemblyReferences = GetPackageAssemblyReferenceList(package, currentResult);

                //Prune dependency list based on additional assemblies included in the package...
                actualAssemblyReferences = RemoveInternallySatisfiedDependencies(actualAssemblyReferences, package);

                var packageDependencies = GetDependencyAssemblyList(package, currentResult).ToList();
                actualAssemblyReferences = RemoveAssemblyExclusions(actualAssemblyReferences, currentResult);

                var usedDependencies = new List <IPackage>();
                foreach (var actualDependency in actualAssemblyReferences)
                {
                    var possibles = GetPossiblePackagesForAssembly(actualDependency, packageDependencies).ToList();
                    usedDependencies.AddRange(possibles.Select(p => p));
                    if (!possibles.Any())
                    {
                        currentResult.UnresolvedAssemblyReferences.Add(actualDependency);
                        if (_checkForFeedResolvableAssemblies)
                        {
                            //May be expensive....
                            if (GetPossiblePackagesForAssembly(actualDependency, _feedPackages).Any())
                            {
                                currentResult.FeedResolvableReferences.Add(actualDependency);
                            }
                        }

                        if (_checkGac)
                        {
                            if (CanResolveToGac(actualDependency.FullName) || CanResolveToGac(actualDependency.Name))
                            {
                                currentResult.GacResolvableReferences.Add(actualDependency);
                            }
                        }
                    }
                    else
                    {
                        currentResult.ResolvedAssemblyReferences.Add(actualDependency);
                    }
                }

                currentResult.UsedPackageDependencies.AddRange(packageDependencies.Where(usedDependencies.Contains).Select(l => l));
                currentResult.UnusedPackageDependencies.AddRange(packageDependencies.Where(p => !usedDependencies.Contains(p)).Select(l => l));
                _results.Add(currentResult);
                FinishedPackageAudit(this, new PackageAuditEventArgs {
                    Package = package
                });
            }
            _unresolvableAssemblyReferences = GetUnresolvedAssemblies(_results);
            UpdateUnresolvablePackageAuditResults(_results, _unresolvableAssemblyReferences);
            return(_results);
        }
Пример #3
0
        /// <summary>
        /// Gets a list of AssemblyNames referenced by the files in a package
        /// </summary>
        /// <param name="package">The package to check.</param>
        /// <param name="result">A result to append errors to.</param>
        /// <returns></returns>
        private static IEnumerable <AssemblyName> GetPackageAssemblyReferenceList(IPackage package, PackageAuditResult result)
        {
            var actualDependencies = new List <AssemblyName>();

            foreach (var file in package.GetFiles().Where(f => f.Path.EndsWith(".dll") || f.Path.EndsWith("*.exe")))
            {
                using (var stream = file.GetStream())
                {
                    try
                    {
                        var assembly = Assembly.Load(stream.ReadAllBytes());
                        actualDependencies.AddRange(assembly.GetReferencedAssemblies());
                    }
                    catch (Exception)
                    {
                        result.UnloadablePackageFiles.Add(file.Path);
                    }
                }
            }
            return(actualDependencies.Where(d => !IsProbablySystemAssembly(d)).Distinct(new AssemblyNameEqualityComparer()));
        }
Пример #4
0
        private IEnumerable <AssemblyName> RemoveAssemblyExclusions(IEnumerable <AssemblyName> actualAssemblyReferences, PackageAuditResult currentResult)
        {
            var actualAssemblyReferencesList = actualAssemblyReferences.ToList();
            var assemblyReferences           = new List <AssemblyName>(actualAssemblyReferencesList);

            foreach (var assembly in actualAssemblyReferencesList)
            {
                if (_assemblyWildcards.Any(w => w.IsMatch(assembly.Name.ToLowerInvariant())))
                {
                    assemblyReferences.Remove(assembly);
                    currentResult.AuditExclusionReferences.Add(assembly);
                }

                if (_assemblyExceptions.Any(e => e.Equals(assembly.Name, StringComparison.OrdinalIgnoreCase)))
                {
                    assemblyReferences.Remove(assembly);
                    currentResult.AuditExclusionReferences.Add(assembly);
                }
            }

            return(assemblyReferences);
        }
Пример #5
0
        /// <summary>
        /// Audits a feed and provides back a set of results
        /// </summary>
        /// <returns></returns>
        public List<PackageAuditResult> Audit(IPackage packageToAudit = null)
        {
            StartPackageListDownload(this, new EventArgs());
            _feedPackages = _packageRepository.GetPackages().Where(p => p.IsLatestVersion).OrderBy(p => p.Id).ToList();
            FinishedPackageListDownload(this, new EventArgs());

            //If we are auditing the whole feed, use the whole feed as the audit package list.....
            _auditPackages = packageToAudit == null ? _feedPackages : new List<IPackage>(new[] {packageToAudit});

            foreach (var package in _auditPackages)
            {
                //OData wont let us query this remotely (again, f**k OData).
                if (_unlisted == false && package.Listed == false) continue;
                
                StartPackageAudit(this, new PackageAuditEventArgs {Package = package});

                //Try the next one if we are using this one as an exception
                if (_wildcards.Any(w => w.IsMatch(package.Id.ToLowerInvariant())))
                {
                    PackageIgnored(this, new PackageIgnoreEventArgs {IgnoredPackage = package, Wildcard = true});
                    continue;
                }
                if (_exceptions.Any(e => e.Equals(package.Id,StringComparison.OrdinalIgnoreCase)))
                {
                    PackageIgnored(this, new PackageIgnoreEventArgs { IgnoredPackage = package, StringMatch = true });
                    continue;
                }

                var currentResult = new PackageAuditResult {Package = package};
                var actualAssemblyReferences = GetPackageAssemblyReferenceList(package, currentResult);

                //Prune dependency list based on additional assemblies included in the package...
                actualAssemblyReferences = RemoveInternallySatisfiedDependencies(actualAssemblyReferences, package);

                var packageDependencies = GetDependencyAssemblyList(package, currentResult).ToList();
                actualAssemblyReferences = RemoveAssemblyExclusions(actualAssemblyReferences, currentResult);

                var usedDependencies = new List<IPackage>();
                foreach (var actualDependency in actualAssemblyReferences)
                {
                    var possibles = GetPossiblePackagesForAssembly(actualDependency, packageDependencies).ToList();
                    usedDependencies.AddRange(possibles.Select(p => p));
                    if (!possibles.Any())
                    {
                        currentResult.UnresolvedAssemblyReferences.Add(actualDependency);
                        if (_checkForFeedResolvableAssemblies)
                        {
                            //May be expensive....
                            if (GetPossiblePackagesForAssembly(actualDependency, _feedPackages).Any())
                                currentResult.FeedResolvableReferences.Add(actualDependency);
                        }

                        if (_checkGac)
                        {
                            if (CanResolveToGac(actualDependency.FullName) || CanResolveToGac(actualDependency.Name))
                                currentResult.GacResolvableReferences.Add(actualDependency);
                        }
                    }
                    else
                        currentResult.ResolvedAssemblyReferences.Add(actualDependency);
                }

                currentResult.UsedPackageDependencies.AddRange(packageDependencies.Where(usedDependencies.Contains).Select(l => l));
                currentResult.UnusedPackageDependencies.AddRange(packageDependencies.Where(p => !usedDependencies.Contains(p)).Select(l => l));
                _results.Add(currentResult);
                FinishedPackageAudit(this, new PackageAuditEventArgs{Package = package});
            }
            _unresolvableAssemblyReferences = GetUnresolvedAssemblies(_results);
            UpdateUnresolvablePackageAuditResults(_results, _unresolvableAssemblyReferences);
            return _results;
        }
Пример #6
0
 /// <summary>
 /// Gets a list of AssemblyNames referenced by the files in a package
 /// </summary>
 /// <param name="package">The package to check.</param>
 /// <param name="result">A result to append errors to.</param>
 /// <returns></returns>
 private static IEnumerable<AssemblyName> GetPackageAssemblyReferenceList(IPackage package, PackageAuditResult result)
 {
     var actualDependencies = new List<AssemblyName>();
     foreach (var file in package.GetFiles().Where(f => f.Path.EndsWith(".dll") || f.Path.EndsWith("*.exe")))
     {
         using (var stream = file.GetStream())
         {
             try
             {
                 var assembly = Assembly.Load(stream.ReadAllBytes());
                 actualDependencies.AddRange(assembly.GetReferencedAssemblies());
             }
             catch (Exception)
             {
                 result.UnloadablePackageFiles.Add(file.Path);
             }
         }
     }
     return actualDependencies.Where(d => !IsProbablySystemAssembly(d)).Distinct(new AssemblyNameEqualityComparer());
 }
Пример #7
0
 /// <summary>
 /// Returns a dictionary mapping of IPackages to their included files.
 /// </summary>
 /// <param name="package"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 private IEnumerable<IPackage> GetDependencyAssemblyList(IPackage package, PackageAuditResult result)
 {
     var packageDependencies = new List<IPackage>();
     foreach (var dependency in package.DependencySets.SelectMany(s => s.Dependencies))
     {
         //HACK Slow and wrong and evil and I HATE ODATA.
         var dependencyPackage = _feedPackages.FirstOrDefault(p => p.Id.Equals(dependency.Id, StringComparison.OrdinalIgnoreCase));
         if (dependencyPackage == null)
         {
             result.UnresolvedDependencies.Add(dependency);
             continue;
         }
         packageDependencies.Add(dependencyPackage);
     }
     return packageDependencies;
 }
Пример #8
0
        private IEnumerable<AssemblyName> RemoveAssemblyExclusions(IEnumerable<AssemblyName> actualAssemblyReferences, PackageAuditResult currentResult)
        {
	        var actualAssemblyReferencesList = actualAssemblyReferences.ToList();
			var assemblyReferences = new List<AssemblyName>(actualAssemblyReferencesList);
			foreach (var assembly in actualAssemblyReferencesList)
            {
                if (_assemblyWildcards.Any(w => w.IsMatch(assembly.Name.ToLowerInvariant())))
                {
                    assemblyReferences.Remove(assembly);
                    currentResult.AuditExclusionReferences.Add(assembly);
                }

                if (_assemblyExceptions.Any(e => e.Equals(assembly.Name, StringComparison.OrdinalIgnoreCase)))
                {
                    assemblyReferences.Remove(assembly);
                    currentResult.AuditExclusionReferences.Add(assembly);
                }
            }

            return assemblyReferences;
        }