/// <summary>
        /// Returns the path to all referenced xprojs by using the package spec resolver.
        /// This will return references for ALL TxMs. Filtering based on the nearest TxM
        /// is needed to apply these results.
        /// </summary>
        /// <param name="filePath">Full path to the .xproj file.</param>
        public static List <string> GetProjectReferences(string filePath)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            var output = new List <string>();

            if (filePath.EndsWith(XProjExtension, StringComparison.OrdinalIgnoreCase))
            {
                var dir      = Path.GetDirectoryName(filePath);
                var jsonPath = Path.Combine(dir, PackageSpec.PackageSpecFileName);

                // Ignore invalid projects with no project.json
                if (File.Exists(jsonPath))
                {
                    var projectName = Path.GetFileNameWithoutExtension(filePath);
                    var spec        = JsonPackageSpecReader.GetPackageSpec(projectName, jsonPath);

                    var resolver = new PackageSpecResolver(spec);

                    // combine all dependencies
                    // This will include references for every TxM, these will have to be filtered later
                    var dependencies = new HashSet <LibraryDependency>();
                    dependencies.UnionWith(spec.Dependencies.Where(d => IsProjectReference(d)));
                    dependencies.UnionWith(spec.TargetFrameworks
                                           .SelectMany(f => f.Dependencies)
                                           .Where(d => IsProjectReference(d)));

                    // Attempt to look up each dependency
                    foreach (var dependency in dependencies)
                    {
                        PackageSpec childSpec;
                        if (resolver.TryResolvePackageSpec(dependency.Name, out childSpec))
                        {
                            var fileInfo = new FileInfo(childSpec.FilePath);

                            // dir/ProjectName.xproj
                            var xprojPath = Path.Combine(
                                fileInfo.DirectoryName,
                                fileInfo.Directory.Name + XProjExtension);

                            output.Add(xprojPath);
                        }
                    }
                }
            }

            return(output);
        }
Ejemplo n.º 2
0
        public async Task<RestoreResult> ExecuteAsync(RestoreRequest request)
        {
            if (request.Project.TargetFrameworks.Count == 0)
            {
                _log.LogError("The project does not specify any target frameworks!");
                return new RestoreResult(success: false, restoreGraphs: Enumerable.Empty<RestoreTargetGraph>());
            }

            var projectLockFilePath = string.IsNullOrEmpty(request.LockFilePath) ?
                Path.Combine(request.Project.BaseDirectory, LockFileFormat.LockFileName) :
                request.LockFilePath;

            _log.LogInformation($"Restoring packages for '{request.Project.FilePath}'");

            _log.LogWarning("TODO: Read and use lock file");

            // Load repositories
            var projectResolver = new PackageSpecResolver(request.Project);
            var nugetRepository = Repository.Factory.GetCoreV3(request.PackagesDirectory);

            var context = new RemoteWalkContext();

            ExternalProjectReference exterenalProjectReference = null;
            if (request.ExternalProjects.Any())
            {
                exterenalProjectReference = new ExternalProjectReference(
                    request.Project.Name, 
                    request.Project.FilePath, 
                    request.ExternalProjects.Select(p => p.Name));
            }

            context.ProjectLibraryProviders.Add(
                new LocalDependencyProvider(
                    new PackageSpecReferenceDependencyProvider(projectResolver, exterenalProjectReference)));

            if (request.ExternalProjects != null)
            {
                context.ProjectLibraryProviders.Add(
                    new LocalDependencyProvider(
                        new ExternalProjectReferenceDependencyProvider(request.ExternalProjects)));
            }

            context.LocalLibraryProviders.Add(
                new SourceRepositoryDependencyProvider(nugetRepository, _log));

            foreach (var provider in request.Sources.Select(s => CreateProviderFromSource(s, request.NoCache)))
            {
                context.RemoteLibraryProviders.Add(provider);
            }

            var remoteWalker = new RemoteDependencyWalker(context);

            var projectRange = new LibraryRange()
            {
                Name = request.Project.Name,
                VersionRange = new VersionRange(request.Project.Version),
                TypeConstraint = LibraryTypes.Project
            };

            // Resolve dependency graphs
            var frameworks = request.Project.TargetFrameworks.Select(f => f.FrameworkName).ToList();
            var graphs = new List<RestoreTargetGraph>();
            var frameworkTasks = new List<Task<RestoreTargetGraph>>();

            foreach (var framework in frameworks)
            {
                frameworkTasks.Add(WalkDependencies(projectRange, framework, remoteWalker, context));
            }

            graphs.AddRange(await Task.WhenAll(frameworkTasks));

            if (graphs.Any(g => g.InConflict))
            {
                _log.LogError("Failed to resolve conflicts");
                return new RestoreResult(success: false, restoreGraphs: graphs);
            }

            // Install the runtime-agnostic packages
            var allInstalledPackages = new HashSet<LibraryIdentity>();
            var localRepository = new NuGetv3LocalRepository(request.PackagesDirectory, checkPackageIdCase: false);
            await InstallPackages(graphs, request.PackagesDirectory, allInstalledPackages, request.MaxDegreeOfConcurrency);

            // Resolve runtime dependencies
            var runtimeGraphs = new List<RestoreTargetGraph>();
            if (request.Project.RuntimeGraph.Runtimes.Count > 0)
            {
                var runtimeTasks = new List<Task<RestoreTargetGraph[]>>();
                foreach (var graph in graphs)
                {
                    runtimeTasks.Add(WalkRuntimeDependencies(projectRange, graph, request.Project.RuntimeGraph, remoteWalker, context, localRepository));
                }

                foreach (var runtimeSpecificGraphs in await Task.WhenAll(runtimeTasks))
                {
                    runtimeGraphs.AddRange(runtimeSpecificGraphs);
                }

                graphs.AddRange(runtimeGraphs);

                if (runtimeGraphs.Any(g => g.InConflict))
                {
                    _log.LogError("Failed to resolve conflicts");
                    return new RestoreResult(success: false, restoreGraphs: graphs);
                }

                // Install runtime-specific packages
                await InstallPackages(runtimeGraphs, request.PackagesDirectory, allInstalledPackages, request.MaxDegreeOfConcurrency);
            }
            else
            {
                _log.LogVerbose("Skipping runtime dependency walk, no runtimes defined in project.json");
            }

            // Build the lock file
            var repository = new NuGetv3LocalRepository(request.PackagesDirectory, checkPackageIdCase: false);
            var lockFile = CreateLockFile(request.Project, graphs, repository);
            var lockFileFormat = new LockFileFormat();
            lockFileFormat.Write(projectLockFilePath, lockFile);

            // Generate Targets/Props files
            WriteTargetsAndProps(request.Project, graphs, repository);

            return new RestoreResult(true, graphs, lockFile);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Create a <see cref="RuntimeHostBuilder"/> for the project in the specified
        /// <paramref name="projectDirectory"/>, using the default configuration.
        /// </summary>
        /// <remarks>
        /// This method will throw if the project.json file cannot be found in the
        /// specified folder. If a project.lock.json file is present in the directory
        /// it will be loaded.
        /// </remarks>
        /// <param name="projectDirectory">The directory of the project to host</param>
        public static RuntimeHostBuilder ForProjectDirectory(string projectDirectory, NuGetFramework runtimeFramework, IServiceProvider services)
        {
            if (string.IsNullOrEmpty(projectDirectory))
            {
                throw new ArgumentNullException(nameof(projectDirectory));
            }
            if (runtimeFramework == null)
            {
                throw new ArgumentNullException(nameof(runtimeFramework));
            }

            var log = RuntimeLogging.Logger<RuntimeHostBuilder>();
            var hostBuilder = new RuntimeHostBuilder();

            // Load the Project
            var projectResolver = new PackageSpecResolver(projectDirectory);
            PackageSpec packageSpec;
            if (projectResolver.TryResolvePackageSpec(GetProjectName(projectDirectory), out packageSpec))
            {
                log.LogVerbose($"Loaded project {packageSpec.Name}");
                hostBuilder.Project = new Project(packageSpec);
            }
            hostBuilder.GlobalSettings = projectResolver.GlobalSettings;

            // Load the Lock File if present
            LockFile lockFile;
            if (TryReadLockFile(projectDirectory, out lockFile))
            {
                log.LogVerbose($"Loaded lock file");
                hostBuilder.LockFile = lockFile;
            }

            // Set the framework and other components
            hostBuilder.TargetFramework = runtimeFramework;
            hostBuilder.Services = services;
            hostBuilder.PackagePathResolver = new PackagePathResolver(
                ResolveRepositoryPath(hostBuilder.GlobalSettings),
                GetCachePaths());

            log.LogVerbose("Registering PackageSpecReferenceDependencyProvider");
            hostBuilder.DependencyProviders.Add(new PackageSpecReferenceDependencyProvider(projectResolver));

            if (hostBuilder.LockFile != null)
            {
                log.LogVerbose("Registering LockFileDependencyProvider");
                hostBuilder.DependencyProviders.Add(new LockFileDependencyProvider(hostBuilder.LockFile));
            }

            log.LogVerbose("Registering ReferenceAssemblyDependencyProvider");
            var referenceResolver = new FrameworkReferenceResolver();
            hostBuilder.DependencyProviders.Add(new ReferenceAssemblyDependencyProvider(referenceResolver));

            // GAC resolver goes here! :)

            return hostBuilder;
        }