Ejemplo n.º 1
0
        public async Task PreProcess(string directive, ScriptExecutionContext context, Action <string> logger)
        {
            var    actionLogger   = new NugetLogger(logger);
            var    nugetDirective = NugetPreProcessorDirective.Parse(directive);
            string frameworkName  = Assembly.GetEntryAssembly() !.GetCustomAttributes(true)
                                    .OfType <System.Runtime.Versioning.TargetFrameworkAttribute>()
                                    .Select(x => x.FrameworkName)
                                    .FirstOrDefault() !;
            NuGetFramework framework = frameworkName == null
              ? NuGetFramework.AnyFramework
              : NuGetFramework.ParseFrameworkName(frameworkName, new DefaultFrameworkNameProvider());

            using var cache = new SourceCacheContext();
            var packagesPath = Path.Combine(Path.GetTempPath(), "packages");

            await CreateEmptyNugetConfig(packagesPath, nugetDirective.FeedUrl);

            var settings = Settings.LoadImmutableSettingsGivenConfigPaths(new[] { Path.Combine(packagesPath, "empty.config") }, new SettingsLoadingContext());

            var availablePackages = new HashSet <SourcePackageDependencyInfo>(PackageIdentityComparer.Default);

            #pragma warning disable CS0618 // Type or member is obsolete
            var repositoryProvider = new SourceRepositoryProvider(settings, Repository.Provider.GetCoreV3());
            #pragma warning restore CS0618 // Type or member is obsolete

            var repository = repositoryProvider.GetRepositories().FirstOrDefault();
            var packageMetadataResource = await repository.GetResourceAsync <PackageMetadataResource>(CancellationToken.None);

            var searchMetadata = await packageMetadataResource.GetMetadataAsync(
                nugetDirective.PackageId,
                includePrerelease : false,
                includeUnlisted : false,
                cache,
                actionLogger,
                CancellationToken.None);

            if (!searchMetadata.Any())
            {
                throw new NuGetResolverException($"Unable to resolve nuget package with id {nugetDirective.PackageId}");
            }

            var latest = searchMetadata.OrderByDescending(a => a.Identity.Version).FirstOrDefault();

            if (latest is null)
            {
                throw new NuGetResolverException($"Unable to resolve nuget package with id {nugetDirective.PackageId}");
            }

            var packageId          = latest.Identity;
            var dependencyResource = await repository.GetResourceAsync <DependencyInfoResource>();

            await GetPackageDependencies(
                packageId,
                framework,
                cache,
                repository,
                dependencyResource,
                availablePackages, actionLogger);

            var resolverContext = new PackageResolverContext(
                DependencyBehavior.Lowest,
                new[] { nugetDirective.PackageId },
                Enumerable.Empty <string>(),
                Enumerable.Empty <PackageReference>(),
                Enumerable.Empty <PackageIdentity>(),
                availablePackages,
                new[] { repository.PackageSource },
                actionLogger);

            var resolver  = new PackageResolver();
            var toInstall = resolver.Resolve(resolverContext, CancellationToken.None)
                            .Select(a => availablePackages.Single(b => PackageIdentityComparer.Default.Equals(b, a)));

            var pathResolver      = new PackagePathResolver(packagesPath);
            var extractionContext = new PackageExtractionContext(
                PackageSaveMode.Defaultv3,
                XmlDocFileSaveMode.None,
                ClientPolicyContext.GetClientPolicy(settings, actionLogger),
                actionLogger);
            var libraries        = new List <string>();
            var frameworkReducer = new FrameworkReducer();
            var downloadResource = await repository.GetResourceAsync <DownloadResource>(CancellationToken.None);

            foreach (var package in toInstall)
            {
                libraries.AddRange(await Install(downloadResource, package, pathResolver, extractionContext, frameworkReducer, framework, packagesPath, actionLogger));
            }

            foreach (var path in libraries)
            {
                var assembly = Assembly.LoadFile(path);
                if (context.TryAddReferenceAssembly(assembly))
                {
                    foreach (var ns in assembly.GetTypes().Select(a => a.Namespace).Distinct())
                    {
                        context.AddImport(ns);
                    }
                }
            }
        }