/// <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));
        }
Beispiel #2
0
        /// <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));
        }