public void LicenseDefaultNotAllowed_InternalProject_NoViolation() { var config = new Config { DiskCache = new DiskCacheConfig { ResolvedLicenses = new DiskCacheItem { DoCache = false } } }; var packagePolicies = new PackagePolicies(new PackagePolicy[] { }); var licensePolicies = new[] { new LicensePolicy { License = "no-distribution-allowed", Allow = false, AllowInternal = true } }; var pd = new PackageDetails { Id = "test-id", Version = "1.0.4", License = "no-distribution-allowed", }; var package = new AnalyzedPackage(pd.Id, pd.Version, "path-to-origin-project"); var dependencies = DependencyChain <AnalyzedPackage> .EmptyList; var packages = new[] { new DependencyChain <AnalyzedPackage>(package, dependencies) }; var scanner = new LicenseScanner(_ => Task.FromResult(new PackageDetailsResult(pd)), packagePolicies, config); var licensedDependencies = scanner.FindLicenses(packages); LicensePolicies licensing = new LicensePolicies(licensePolicies, packagePolicies, new Projects(new[] { "path-to-origin-project" })); var result = licensing.Apply(licensedDependencies); Assert.Equal(1, result.Count); Assert.Equal(Evaluation.Ok, result.First().Package.Result); }
internal async Task <IList <DependencyChain <AnalyzedPackage> > > FindPackageDependencies(IEnumerable <PackageRange> packages, ICollection <string> searchedRoots) { var packagesToResolved = packages .Select(p => (Package: p, Resolved: this.versionResolver.GetSingleVersion(p))) .ToList(); List <DependencyChain <AnalyzedPackage> > result = packagesToResolved .Where(tuple => tuple.Resolved == null) .Select(tuple => new InvalidDependencyChain(tuple.Package, $"Could not find a package with version {tuple.Package.VersionRange}.")) .Cast <DependencyChain <AnalyzedPackage> >() .ToList(); var validPackages = packagesToResolved.Select(t => t.Resolved).ToArray(); Task.WaitAll(validPackages); var valid = validPackages.Where(x => x.Result != null).Select(x => x.Result !); // Separate the packages into those who have a location and those // who do not. The former we will look up on disk, the others in // nuget. var packagesAndLocations = valid.Select(package => (package, location: packagePolicies.GetLocation(package.Id))); var packagesWithLocations = packagesAndLocations.Where(p => p.location != null); var packagesWithoutLocations = packagesAndLocations.Except(packagesWithLocations).Select(p => p.package); { var dependencies = await this.registry.FindPackageDependencies(packagesWithoutLocations); result.AddRange(dependencies); } { foreach (var(package, location) in packagesWithLocations) { if (searchedRoots.Contains(location)) { continue; } var analyzedPackage = new AnalyzedPackage(package); IList <DependencyChain <AnalyzedPackage> > dependencies; if (this.followLocations) { searchedRoots.Add(location); dependencies = await this.FindPackageDependenciesAux(location !, searchedRoots); } else { dependencies = DependencyChain <AnalyzedPackage> .EmptyList; } var chain = new DependencyChain <AnalyzedPackage>(analyzedPackage, dependencies); result.Add(chain); } } return(result); }
internal async Task <DependencyChain <AnalyzedPackage> > FindPackageDependencies(Package package, HashSet <string> upstreamDependencies) { string resolvedDependenciesPath = string.Format(this.resolvedPathFormatStr, package.Id, package.Version); if (DiskCache.TryGetValue(resolvedDependenciesPath, this.config.ResolvedDependencies, out DependencyChain <AnalyzedPackage>?cached)) { return(cached); } string path = string.Format(this.detailsPathFormatStr, package.Id, package.Version); NpmPackage?npmPackage; if (!DiskCache.TryGetValue(path, this.config.PackageDetails, out npmPackage)) { npmPackage = await this.npm.GetPackage(package).ContinueWith(CachePackage); } if (npmPackage == null) { Log.Warning($"Could not find information about {package.Id} {package.Version} from npm"); return(new InvalidDependencyChain(package, "Could not find information from npm")); } var analyzedPackage = new AnalyzedPackage(package); var packageDependencies = npmPackage.Dependencies ?? new Dictionary <string, string>(); var ds = packageDependencies.Select(x => new PackageRange(x.Key, x.Value, package.OriginProject)); var dependencies = await FindPackageDependencies(ds, upstreamDependencies); var result = new DependencyChain <AnalyzedPackage>(analyzedPackage, dependencies); CacheDependencies(package, result); return(result); NpmPackage?CachePackage(Task <(PackageDetailsResultEnum, NpmPackage?)> package) { if (!this.config.PackageDetails.DoCache) { return(package.Result.Item2); } if (package.Result.Item1 != PackageDetailsResultEnum.Success) { return(null); } NpmPackage p = package.Result.Item2 !; string cachePath = string.Format(this.detailsPathFormatStr, p.Id, p.Version); DiskCache.Cache(cachePath, p); return(p); } }
private async Task <DependencyChain <AnalyzedPackage> > FindPackageDependencies(Package package) { string resolvedDependenciesPath = string.Format(this.resolvedPathFormatStr, package.Id, package.Version); if (DiskCache.TryGetValue(resolvedDependenciesPath, this.config.ResolvedDependencies, out DependencyChain <AnalyzedPackage>?cached)) { return(cached); } var(status, packageDetails) = await GetPackageDetails(package); if (status == PackageDetailsResultEnum.InternalPackage) { var analyzedPackage = new AnalyzedPackage(package.Id, package.Version, package.OriginProject, AnalysisState.Ok, string.Empty); return(new DependencyChain <AnalyzedPackage>(analyzedPackage, DependencyChain <AnalyzedPackage> .EmptyList)); } else if (status != PackageDetailsResultEnum.Success) { return(new InvalidDependencyChain(package, "Could not find any package information.")); } else if (packageDetails == null) { throw new InvalidOperationException($"Got a null result even though status indicated success: {package}"); } List <DependencyChain <AnalyzedPackage> > result = new List <DependencyChain <AnalyzedPackage> >(); foreach (var group in packageDetails.DependencyGroups ?? EmptyDependencyGroups) { var dependencies = await FindPackageDependenciesAux(group.Dependencies ?? EmptyDependencies, false); result.AddRange(dependencies); } var uniqueDependencies = result.Distinct(DependencyComparer).ToList(); if (uniqueDependencies.Any()) { Log.Debug($"{package}: dependencies - {string.Join(", ", uniqueDependencies.Select(y => y.Package.ToString()))}"); } else { Log.Debug($"{package}: no dependencies"); } return(new DependencyChain <AnalyzedPackage>(new AnalyzedPackage(package), uniqueDependencies)); }
public void NoPackageFound_HasValidPackagePolicy_GivesCorrectLicense() { var config = new Config(); var packagePolicies = new PackagePolicies(new[] { new PackagePolicy { Package = "test-id", License = "test-license" } }); var scanner = new LicenseScanner(_ => Task.FromResult(new PackageDetailsResult(PackageDetailsResultEnum.NoPackageFound)), packagePolicies, config); var package = new AnalyzedPackage("test-id", "1.0.4", string.Empty, AnalysisState.Error, "test error"); var dependencies = DependencyChain <AnalyzedPackage> .EmptyList; var packages = new[] { new DependencyChain <AnalyzedPackage>(package, dependencies) }; var result = scanner.FindLicenses(packages); Assert.Equal(1, result.Count); Assert.Equal("test-license", result.First().Package.License); }