/// <summary> /// Recursively try to find licenses for all packages in a dependency /// chain. /// </summary> public async Task <DependencyChain <LicensedPackage> > GetLicensesAsync(DependencyChain <AnalyzedPackage> chain) { var rootLicense = await GetLicenseAsync(chain.Package); string path = string.Format(this.licensePathFormatStr, chain.Package.Id, chain.Package.Version); DiskCache.Cache(path, new ResolvedLicense(rootLicense.License, rootLicense.State, rootLicense.Messages)); var dependencyLicensesTasks = chain.Dependencies.Select(GetLicensesAsync).ToArray(); Task.WaitAll(dependencyLicensesTasks); var dependencyLicenses = dependencyLicensesTasks.Select(x => x.Result).ToList(); return(new DependencyChain <LicensedPackage>(rootLicense, dependencyLicenses)); }
/// <summary> /// Tries to find the license identifier based on the text in the /// license file. /// </summary> public async Task <(License?, string)> TryGetLicenseFromLicenseFile(Uri licenseUrl) { string path = Path.Combine(licenceFileDirectory, Normalize(licenseUrl), "LICENSE"); if (!DiskCache.TryGetValue(path, this.config.DiskCache.LicenseFiles, out string?licenseText)) { try { licenseText = await SharedHttpClient.GetStringAsync(licenseUrl).ConfigureAwait(false); } catch (Exception e) { string message = $"Error getting license file from {licenseUrl}: {e.Message}"; Log.Warning(message); return(null, message); } DiskCache.CacheData(path, licenseText); } return(await this.licenseDetector.Detect(Path.GetDirectoryName(path)).ConfigureAwait(false)); }
private async Task <LicensedPackage> GetLicenseAsync(AnalyzedPackage package) { if (this.licenseProvider.TryGetLicense(package.Id, out string explicitLicense)) { return(package.With(AnalysisState.Ok, "Given by config.").Attach(new License(explicitLicense))); } if (package.State == AnalysisState.Error) { return(package.Attach(License.NonEvaluated)); } string path = string.Format(this.licensePathFormatStr, package.Id, package.Version); if (DiskCache.TryGetValue(path, this.config.DiskCache.ResolvedLicenses, out ResolvedLicense? cachedLicense)) { return(new LicensedPackage(package.Id, package.Version, package.OriginProject, cachedLicense.License, cachedLicense.State, cachedLicense.Messages)); } var details = await this.getDetails(package); if (details.Status == PackageDetailsResultEnum.InternalPackage) { return(package .With(AnalysisState.Ok, "Internal package. No explicit license given.") .Attach(License.Internal)); } else if (details.Status == PackageDetailsResultEnum.NoPackageFound) { Log.Error($"Could not find information on package {package}"); return(package .With(AnalysisState.Error, $"Could not find information on package") .Attach(License.NonEvaluated)); } var packageDetails = details.Package !; if (packageDetails.License != null) { return(new LicensedPackage(package.Id, package.Version, package.OriginProject, packageDetails.License)); } string deprecated = "https://aka.ms/deprecateLicenseUrl"; if (packageDetails.LicenseUrl == null || packageDetails.LicenseUrl.ToString() == deprecated) { Log.Information($"{package} has no valid license URL (will try to fetch from repository)"); return(await GetLicenseFromProject(package, packageDetails.PackageUrl)); } if (this.licenseParsing.TryGetLicenseFromKnownUrl(packageDetails.LicenseUrl, out License? license)) { return(package.Attach(license)); } Uri licenseUrl = ChangeGithubLicenseUrl(packageDetails.LicenseUrl); string error; (license, error) = await this.licenseParsing.TryGetLicenseFromLicenseFile(licenseUrl); if (license != null) { return(package.Attach(license)); } Log.Debug($"Could not find license for package {package}: " + error); return(package.With(AnalysisState.Ok, error ?? string.Empty).Attach(License.UnknownLicense)); }