public async Task RestoreBuildTargetsAndProps_VerifyPropsAndTargetsGeneratedWithNoTFMConditionsAsync()
        {
            // Arrange
            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var logger  = new TestLogger();
                    var sources = new List <PackageSource>
                    {
                        new PackageSource(pathContext.PackageSource)
                    };

                    var spec = GetProject("projectA", "net462");

                    spec.RestoreMetadata.CrossTargeting = false;
                    spec.Dependencies.Add(new LibraryDependency()
                    {
                        LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package)
                    });

                    // Create fake projects, the real data is in the specs
                    var projects = CreateProjectsFromSpecs(pathContext, spec);

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();
                    dgFile.AddProject(spec);
                    dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName);
                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    var packageX = new SimpleTestPackageContext()
                    {
                        Id      = "x",
                        Version = "1.0.0"
                    };

                    packageX.AddFile("build/x.targets");
                    packageX.AddFile("build/x.props");
                    packageX.AddFile("contentFiles/any/any/_._");

                    await SimpleTestPackageUtility.CreatePackagesAsync(pathContext.PackageSource, packageX);

                    var project = projects[0];

                    // Act
                    var summaries = await RunRestoreAsync(pathContext, logger, sources, dgFile, cacheContext);

                    var success = summaries.All(s => s.Success);

                    // Assert
                    Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));

                    var targetsXML       = XDocument.Parse(File.ReadAllText(project.TargetsOutput));
                    var targetItemGroups = targetsXML.Root.Elements().Where(e => e.Name.LocalName == "ImportGroup").ToList();

                    var propsXML        = XDocument.Parse(File.ReadAllText(project.PropsOutput));
                    var propsItemGroups = propsXML.Root.Elements().Where(e => e.Name.LocalName == "ImportGroup").ToList();

                    Assert.Equal("'$(ExcludeRestorePackageImports)' != 'true'", targetItemGroups[0].Attribute(XName.Get("Condition")).Value.Trim());
                    Assert.Equal("'$(ExcludeRestorePackageImports)' != 'true'", propsItemGroups[0].Attribute(XName.Get("Condition")).Value.Trim());
                }
        }
예제 #2
0
        public void Json_WhenDgSpecWasCreatedWithBoolConstructor_ReturnsEmptyObject()
        {
            var dgSpec = new DependencyGraphSpec(isReadOnly: true);

            Assert.Empty(dgSpec.Json);
        }
        /// <summary>
        /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json).
        /// </summary>
        /// <param name="projectPath">The full path to the project.</param>
        /// <param name="id">The ID of the package.</param>
        /// <param name="version">The version of the package.</param>
        /// <param name="settings">The NuGet settings to use.</param>
        /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param>
        /// <returns></returns>
        public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(string projectPath, string id, string version, ISettings settings, ILogger logger)
        {
            using (SourceCacheContext sourceCacheContext = new SourceCacheContext
            {
                IgnoreFailedSources = true,
            })
            {
                // The package spec details what packages to restore
                PackageSpec packageSpec = new PackageSpec(TargetFrameworks.Select(i => new TargetFrameworkInformation
                {
                    FrameworkName = i,
                }).ToList())
                {
                    Dependencies = new List <LibraryDependency>
                    {
                        new LibraryDependency
                        {
                            LibraryRange   = new LibraryRange(id, new VersionRange(NuGetVersion.Parse(version)), LibraryDependencyTarget.Package),
                            SuppressParent = LibraryIncludeFlags.All,
                            AutoReferenced = true,
                            IncludeType    = LibraryIncludeFlags.None,
                            Type           = LibraryDependencyType.Build
                        }
                    },
                    RestoreMetadata = new ProjectRestoreMetadata
                    {
                        ProjectPath              = projectPath,
                        ProjectName              = Path.GetFileNameWithoutExtension(projectPath),
                        ProjectStyle             = ProjectStyle.PackageReference,
                        ProjectUniqueName        = projectPath,
                        OutputPath               = Path.GetTempPath(),
                        OriginalTargetFrameworks = TargetFrameworks.Select(i => i.ToString()).ToList(),
                        ConfigFilePaths          = SettingsUtility.GetConfigFilePaths(settings).ToList(),
                        PackagesPath             = SettingsUtility.GetGlobalPackagesFolder(settings),
                        Sources         = SettingsUtility.GetEnabledSources(settings).ToList(),
                        FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                    },
                    FilePath = projectPath,
                    Name     = Path.GetFileNameWithoutExtension(projectPath),
                };

                DependencyGraphSpec dependencyGraphSpec = new DependencyGraphSpec();

                dependencyGraphSpec.AddProject(packageSpec);

                dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);

                IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                RestoreArgs restoreArgs = new RestoreArgs
                {
                    AllowNoOp             = true,
                    CacheContext          = sourceCacheContext,
                    CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)),
                    Log = logger,
                };

                // Create requests from the arguments
                IReadOnlyList <RestoreSummaryRequest> requests = requestProvider.CreateRequests(restoreArgs).Result;

                // Restore the package without generating extra files
                return(RestoreRunner.RunWithoutCommit(requests, restoreArgs));
            }
        }
예제 #4
0
        public static async Task <(RestoreRequest, RestoreResult)> Restore(ILogger logger, NuGetFramework nugetFramework, string runtimeIdentifier, string packageName, VersionRange versionRange)
        {
            var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null);

            var assemblies = new List <string>();

            var projectPath = Path.Combine("StrideNugetResolver.json");
            var spec        = new PackageSpec()
            {
                Name         = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency
                FilePath     = projectPath,
                Dependencies = new List <LibraryDependency>()
                {
                    new LibraryDependency
                    {
                        LibraryRange = new LibraryRange(packageName, versionRange, LibraryDependencyTarget.Package),
                    }
                },
                TargetFrameworks =
                {
                    new TargetFrameworkInformation
                    {
                        FrameworkName = nugetFramework,
                    }
                },
                RestoreMetadata = new ProjectRestoreMetadata
                {
                    ProjectPath              = projectPath,
                    ProjectName              = Path.GetFileNameWithoutExtension(projectPath),
                    ProjectStyle             = ProjectStyle.PackageReference,
                    ProjectUniqueName        = projectPath,
                    OutputPath               = Path.Combine(Path.GetTempPath(), $"StrideNugetResolver-{packageName}-{versionRange.MinVersion.ToString()}-{nugetFramework.GetShortFolderName()}-{runtimeIdentifier}"),
                    OriginalTargetFrameworks = new[] { nugetFramework.GetShortFolderName() },
                    ConfigFilePaths          = settings.GetConfigFilePaths(),
                    PackagesPath             = SettingsUtility.GetGlobalPackagesFolder(settings),
                    Sources         = SettingsUtility.GetEnabledSources(settings).ToList(),
                    FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                },
                RuntimeGraph = new RuntimeGraph(new[] { new RuntimeDescription(runtimeIdentifier) }),
            };

            using (var context = new SourceCacheContext())
            {
                context.IgnoreFailedSources = true;

                var dependencyGraphSpec = new DependencyGraphSpec();

                dependencyGraphSpec.AddProject(spec);

                dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName);

                IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                var restoreArgs = new RestoreArgs
                {
                    AllowNoOp             = true,
                    CacheContext          = context,
                    CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)),
                    Log = logger,
                };

                // Create requests from the arguments
                var requests = requestProvider.CreateRequests(restoreArgs).Result;

                // Restore the packages
                for (int tryCount = 0; tryCount < 2; ++tryCount)
                {
                    try
                    {
                        var results = await RestoreRunner.RunWithoutCommit(requests, restoreArgs);

                        // Commit results so that noop cache works next time
                        foreach (var result in results)
                        {
                            await result.Result.CommitAsync(logger, CancellationToken.None);
                        }
                        var mainResult = results.First();
                        return(mainResult.SummaryRequest.Request, mainResult.Result);
                    }
                    catch (Exception e) when(e is UnauthorizedAccessException || e is IOException)
                    {
                        // If we have an unauthorized access exception, it means assemblies are locked by running Stride process
                        // During first try, kill some known harmless processes, and try again
                        if (tryCount == 1)
                        {
                            throw;
                        }

                        foreach (var process in new[] { "Stride.ConnectionRouter" }.SelectMany(Process.GetProcessesByName))
                        {
                            try
                            {
                                if (process.Id != Process.GetCurrentProcess().Id)
                                {
                                    process.Kill();
                                    process.WaitForExit();
                                }
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }

                throw new InvalidOperationException("Unreachable code");
            }
        }
예제 #5
0
        /******************
        * ToolReferences *
        ******************/

        internal static void ProcessToolReferences(ProjectNames projectNames, IEnumerable targetFrameworks, IVsReferenceItems toolReferences, DependencyGraphSpec dgSpec)
        {
            var toolFramework   = GetToolFramework(targetFrameworks);
            var packagesPath    = GetRestoreProjectPath(targetFrameworks);
            var fallbackFolders = GetRestoreFallbackFolders(targetFrameworks).AsList();
            var sources         = GetRestoreSources(targetFrameworks)
                                  .Select(e => new PackageSource(e))
                                  .ToList();

            toolReferences
            .Cast <IVsReferenceItem>()
            .Select(r => ToolRestoreUtility.GetSpec(
                        projectNames.FullName,
                        r.Name,
                        GetVersionRange(r),
                        toolFramework,
                        packagesPath,
                        fallbackFolders,
                        sources,
                        projectWideWarningProperties: null))
            .ForEach(ts =>
            {
                dgSpec.AddRestore(ts.RestoreMetadata.ProjectUniqueName);
                dgSpec.AddProject(ts);
            });
        }
예제 #6
0
        private void AddInputsFromDependencyGraphSpec(PackageRestoreInputs packageRestoreInputs, DependencyGraphSpec dgFileOutput)
        {
            packageRestoreInputs.ProjectReferenceLookup = dgFileOutput;

            // Get top level entries
            var entryPointProjects = dgFileOutput
                                     .Projects
                                     .Where(project => dgFileOutput.Restore.Contains(project.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal))
                                     .ToList();

            // possible packages.config
            // Compare paths case-insenstive here since we do not know how msbuild modified them
            // find all projects that are not part of the v3 group
            var v2RestoreProjects =
                packageRestoreInputs.ProjectFiles
                .Where(path => !entryPointProjects.Any(project => path.Equals(project.RestoreMetadata.ProjectPath, StringComparison.OrdinalIgnoreCase)));

            packageRestoreInputs.PackagesConfigFiles
            .AddRange(v2RestoreProjects
                      .Select(GetPackagesConfigFile)
                      .Where(path => path != null));

            // Filter down to just the requested projects in the file
            // that support transitive references.
            var v3RestoreProjects = dgFileOutput.Projects
                                    .Where(project => (project.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                                                       project.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson) &&
                                           entryPointProjects.Contains(project));

            packageRestoreInputs.RestoreV3Context.Inputs.AddRange(v3RestoreProjects
                                                                  .Select(project => project.RestoreMetadata.ProjectPath));
        }
 /// <summary>
 /// Persists the dg file for the given restore request.
 /// This does not do a dirty check!
 /// </summary>
 /// <param name="spec">spec</param>
 /// <param name="dgPath">the dg path</param>
 /// <param name="log">logger</param>
 internal static void PersistDGSpecFile(DependencyGraphSpec spec, string dgPath, ILogger log)
 {
     Directory.CreateDirectory(Path.GetDirectoryName(dgPath));
     log.LogVerbose($"Persisting no-op dg to {dgPath}");
     spec.Save(dgPath);
 }
        public async Task DotnetCliTool_ToolRestoreNoOpsRegardlessOfProject()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                var logger1 = new TestLogger();
                var logger2 = new TestLogger();

                var spec1 = ToolRestoreUtility.GetSpec(
                    Path.Combine(pathContext.SolutionRoot, "fake1.csproj"),
                    "a",
                    VersionRange.Parse("1.0.0"),
                    NuGetFramework.Parse("netcoreapp1.0"),
                    pathContext.UserPackagesFolder,
                    new List <string>()
                {
                    pathContext.FallbackFolder
                },
                    new List <PackageSource>()
                {
                    new PackageSource(pathContext.PackageSource)
                },
                    projectWideWarningProperties: null);

                var spec2 = ToolRestoreUtility.GetSpec(
                    Path.Combine(pathContext.SolutionRoot, "fake2.csproj"),
                    "a",
                    VersionRange.Parse("1.0.0"),
                    NuGetFramework.Parse("netcoreapp1.0"),
                    pathContext.UserPackagesFolder,
                    new List <string>()
                {
                    pathContext.FallbackFolder
                },
                    new List <PackageSource>()
                {
                    new PackageSource(pathContext.PackageSource)
                },
                    projectWideWarningProperties: null);

                var dgFile1 = new DependencyGraphSpec();
                dgFile1.AddProject(spec1);
                dgFile1.AddRestore(spec1.Name);

                var dgFile2 = new DependencyGraphSpec();
                dgFile2.AddProject(spec2);
                dgFile2.AddRestore(spec2.Name);

                var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder);
                var path         = pathResolver.GetLockFilePath(
                    "a",
                    NuGetVersion.Parse("1.0.0"),
                    NuGetFramework.Parse("netcoreapp1.0"));

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, new PackageIdentity("a", NuGetVersion.Parse("1.0.0")));

                // Act
                var results1 = await CommandsTestUtility.RunRestore(dgFile1, pathContext, logger1);

                // Assert
                Assert.Equal(1, results1.Count);
                var result1 = results1.Single();

                Assert.True(result1.Success, "Failed: " + string.Join(Environment.NewLine, logger1.Messages));
                Assert.False(result1.NoOpRestore, "Should not no-op: " + string.Join(Environment.NewLine, logger1.Messages));
                Assert.True(File.Exists(path));

                // Act
                var results2 = await CommandsTestUtility.RunRestore(dgFile2, pathContext, logger2);

                // Assert
                Assert.Equal(1, results2.Count);
                var result2 = results2.Single();

                Assert.True(result2.Success, "Failed: " + string.Join(Environment.NewLine, logger2.Messages));
                Assert.True(result2.NoOpRestore, "Should no-op: " + string.Join(Environment.NewLine, logger2.Messages));
                Assert.True(File.Exists(path));
            }
        }
        public async Task DotnetCliTool_VerifyProjectsAreNotAllowed()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                var logger = new TestLogger();
                var dgFile = new DependencyGraphSpec();

                var spec = ToolRestoreUtility.GetSpec(
                    Path.Combine(pathContext.SolutionRoot, "tool", "fake.csproj"),
                    "a",
                    VersionRange.Parse("1.0.0"),
                    NuGetFramework.Parse("netcoreapp1.0"),
                    pathContext.UserPackagesFolder,
                    new List <string>()
                {
                    pathContext.FallbackFolder
                },
                    new List <PackageSource>()
                {
                    new PackageSource(pathContext.PackageSource)
                },
                    projectWideWarningProperties: null);

                dgFile.AddProject(spec);
                dgFile.AddRestore(spec.Name);

                var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder);
                var path         = pathResolver.GetLockFilePath(
                    "a",
                    NuGetVersion.Parse("1.0.0"),
                    NuGetFramework.Parse("netcoreapp1.0"));

                var packageA = new SimpleTestPackageContext()
                {
                    Id      = "a",
                    Version = "1.0.0"
                };

                var packageB = new SimpleTestPackageContext()
                {
                    Id      = "b",
                    Version = "1.0.0"
                };

                packageA.Dependencies.Add(packageB);

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(
                    pathContext.PackageSource,
                    PackageSaveMode.Defaultv3,
                    packageA,
                    packageB);

                var projectYRoot = Path.Combine(pathContext.SolutionRoot, "b");
                Directory.CreateDirectory(projectYRoot);
                var projectYJson = Path.Combine(projectYRoot, "project.json");

                var projectJsonContent = JObject.Parse(@"{
                                                    'dependencies': {
                                                    },
                                                    'frameworks': {
                                                        'netstandard1.0': {
                                                    }
                                                  }
                                               }");

                File.WriteAllText(projectYJson, projectJsonContent.ToString());

                // Act
                var result = await CommandsTestUtility.RunSingleRestore(dgFile, pathContext, logger);

                // Assert
                Assert.True(result.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                Assert.True(File.Exists(path));

                var lockFormat = new LockFileFormat();
                var lockFile   = lockFormat.Read(path);

                // Verify only packages
                Assert.Empty(lockFile.Libraries.Where(e => e.Type != "package"));
            }
        }
        private IReadOnlyList <RestoreSummaryRequest> GetRequestsFromItems(RestoreArgs restoreContext, DependencyGraphSpec dgFile)
        {
            if (restoreContext == null)
            {
                throw new ArgumentNullException(nameof(restoreContext));
            }

            if (dgFile == null)
            {
                throw new ArgumentNullException(nameof(dgFile));
            }

            // Validate the dg file input, this throws if errors are found.
            SpecValidationUtility.ValidateDependencySpec(dgFile);

            // Create requests
            var requests     = new List <RestoreSummaryRequest>();
            var toolRequests = new List <RestoreSummaryRequest>();

            foreach (var projectNameToRestore in dgFile.Restore)
            {
                var closure = dgFile.GetClosure(projectNameToRestore);

                var projectDependencyGraphSpec = dgFile.WithProjectClosure(projectNameToRestore);

                var externalClosure = new HashSet <ExternalProjectReference>(closure.Select(GetExternalProject));

                var rootProject = externalClosure.Single(p =>
                                                         StringComparer.Ordinal.Equals(projectNameToRestore, p.UniqueName));

                var request = Create(projectNameToRestore, rootProject, externalClosure, restoreContext, projectDgSpec: projectDependencyGraphSpec);

                if (request.Request.ProjectStyle == ProjectStyle.DotnetCliTool)
                {
                    // Store tool requests to be filtered later
                    toolRequests.Add(request);
                }
                else
                {
                    requests.Add(request);
                }
            }

            // Filter out duplicate tool restore requests
            requests.AddRange(ToolRestoreUtility.GetSubSetRequests(toolRequests));

            return(requests);
        }
예제 #11
0
        /// <summary>
        /// Fetch, if not already downloaded, and install the package represented by
        /// (<paramref name="packageId"/>, <paramref name="version"/>).
        /// </summary>
        /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks>
        /// <param name="packageId">Name of package to install.</param>
        /// <param name="version">Version of package to install.</param>
        public async Task <NugetLocalPackage> InstallPackage(string packageId, PackageVersion version, ProgressReport progress)
        {
            using (GetLocalRepositoryLock())
            {
                currentProgressReport = progress;
                try
                {
                    var identity = new PackageIdentity(packageId, version.ToNuGetVersion());

                    var resolutionContext = new ResolutionContext(
                        DependencyBehavior.Lowest,
                        true,
                        true,
                        VersionConstraints.None);

                    var repositories = PackageSources.Select(sourceRepositoryProvider.CreateRepository).ToArray();

                    var projectContext = new EmptyNuGetProjectContext()
                    {
                        ActionType = NuGetActionType.Install,
                        PackageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Skip, null, NativeLogger),
                    };

                    ActivityCorrelationId.StartNew();

                    {
                        var installPath = SettingsUtility.GetGlobalPackagesFolder(settings);

                        // Old version expects to be installed in GamePackages
                        if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0) && oldRootDirectory != null)
                        {
                            installPath = oldRootDirectory;
                        }

                        var projectPath = Path.Combine("StrideLauncher.json");
                        var spec        = new PackageSpec()
                        {
                            Name         = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency
                            FilePath     = projectPath,
                            Dependencies = new List <LibraryDependency>()
                            {
                                new LibraryDependency
                                {
                                    LibraryRange = new LibraryRange(packageId, new VersionRange(version.ToNuGetVersion()), LibraryDependencyTarget.Package),
                                }
                            },
                            TargetFrameworks =
                            {
                                new TargetFrameworkInformation
                                {
                                    FrameworkName = NuGetFramework.Parse("net472"),
                                }
                            },
                            RestoreMetadata = new ProjectRestoreMetadata
                            {
                                ProjectPath              = projectPath,
                                ProjectName              = Path.GetFileNameWithoutExtension(projectPath),
                                ProjectStyle             = ProjectStyle.PackageReference,
                                ProjectUniqueName        = projectPath,
                                OutputPath               = Path.Combine(Path.GetTempPath(), $"StrideLauncher-{packageId}-{version.ToString()}"),
                                OriginalTargetFrameworks = new[] { "net472" },
                                ConfigFilePaths          = settings.GetConfigFilePaths(),
                                PackagesPath             = installPath,
                                Sources         = SettingsUtility.GetEnabledSources(settings).ToList(),
                                FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                            },
                        };

                        using (var context = new SourceCacheContext {
                            MaxAge = DateTimeOffset.UtcNow
                        })
                        {
                            context.IgnoreFailedSources = true;

                            var dependencyGraphSpec = new DependencyGraphSpec();

                            dependencyGraphSpec.AddProject(spec);

                            dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName);

                            IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                            var restoreArgs = new RestoreArgs
                            {
                                AllowNoOp             = true,
                                CacheContext          = context,
                                CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)),
                                Log = NativeLogger,
                            };

                            // Create requests from the arguments
                            var requests = requestProvider.CreateRequests(restoreArgs).Result;

                            foreach (var request in requests)
                            {
                                // Limit concurrency to avoid timeout
                                request.Request.MaxDegreeOfConcurrency = 4;

                                var command = new RestoreCommand(request.Request);

                                // Act
                                var result = await command.ExecuteAsync();

                                if (!result.Success)
                                {
                                    throw new InvalidOperationException($"Could not restore package {packageId}");
                                }
                                foreach (var install in result.RestoreGraphs.Last().Install)
                                {
                                    var package = result.LockFile.Libraries.FirstOrDefault(x => x.Name == install.Library.Name && x.Version == install.Library.Version);
                                    if (package != null)
                                    {
                                        var packagePath = Path.Combine(installPath, package.Path);
                                        OnPackageInstalled(this, new PackageOperationEventArgs(new PackageName(install.Library.Name, install.Library.Version.ToPackageVersion()), packagePath));
                                    }
                                }
                            }
                        }

                        if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0))
                        {
                            UpdateTargetsHelper();
                        }
                    }

                    // Load the recently installed package
                    var installedPackages = GetPackagesInstalled(new[] { packageId });
                    return(installedPackages.FirstOrDefault(p => p.Version == version));
                }
                finally
                {
                    currentProgressReport = null;
                }
            }
        }
        // The algorithm here is a 2 pass. In reality the 2nd pass can do a lot but for huge benefits :)
        // Pass #1
        // We check all the specs against the cached ones if any. Any project with a change in the spec is considered dirty.
        // If a project had previously been restored and it failed, it is considered dirty.
        // Every project that is considered to have a dirty spec will be important in pass #2.
        // In the first pass, we also validate the outputs for the projects. Note that these are independent and project specific. Outputs not being up to date it irrelevant for transitivity.
        // Pass #2
        // For every project with a dirty spec (the outputs don't matter here), we want to ensure that its parent projects are marked as dirty as well.
        // This is a bit more expensive since PackageSpecs do not retain pointers to the projects that reference them as ProjectReference.
        // Finally we only update the cache specs if Pass #1 determined that there are projects that are not up to date.
        // Result
        // Lastly all the projects marked as having dirty specs & dirty outputs are returned.
        // Before we return the list of projects that are not up to date, we always make sure to replay the warnings for the up to date projects.
        public IEnumerable <string> PerformUpToDateCheck(DependencyGraphSpec dependencyGraphSpec, ILogger logger)
        {
            if (dependencyGraphSpec == null)
            {
                throw new ArgumentNullException(nameof(dependencyGraphSpec));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (_cachedDependencyGraphSpec != null)
            {
                var  dirtySpecs   = new List <string>();
                var  dirtyOutputs = new List <string>();
                bool hasDirtyNonTransitiveSpecs = false;

                // Pass #1. Validate all the data (i/o)
                // 1a. Validate the package specs (references & settings)
                // 1b. Validate the expected outputs (assets file, nuget.g.*, lock file)
                var unloadedProjects = _restoreData.Keys.ToHashSet();
                foreach (var project in dependencyGraphSpec.Projects)
                {
                    var projectUniqueName = project.RestoreMetadata.ProjectUniqueName;
                    var cache             = _cachedDependencyGraphSpec.GetProjectSpec(projectUniqueName);

                    if (cache == null || !project.Equals(cache))
                    {
                        dirtySpecs.Add(projectUniqueName);
                    }
                    unloadedProjects.Remove(projectUniqueName);

                    if (project.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                        project.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson)
                    {
                        if (!_failedProjects.Contains(projectUniqueName) && _restoreData.TryGetValue(projectUniqueName, out RestoreData restoreData))
                        {
                            GetOutputFilePaths(project, out string assetsFilePath, out string cacheFilePath, out string targetsFilePath, out string propsFilePath, out string lockFilePath);
                            if (!AreOutputsUpToDate(assetsFilePath, cacheFilePath, targetsFilePath, propsFilePath, lockFilePath, project.RestoreMetadata.PackagesPath, restoreData))
                            {
                                dirtyOutputs.Add(projectUniqueName);
                            }
                        }
                        else
                        {
                            dirtyOutputs.Add(projectUniqueName);
                        }
                    }
                    else
                    {
                        hasDirtyNonTransitiveSpecs = true;
                    }
                }

                // Remove the cached data of the unloaded projects if any.
                foreach (var project in unloadedProjects)
                {
                    _restoreData.Remove(project);
                }

                // Fast path. Skip Pass #2
                if (dirtySpecs.Count == 0 && dirtyOutputs.Count == 0)
                {
                    ReplayAllWarnings(_restoreData, (string projectName) => true, logger);
                    return(Enumerable.Empty <string>());
                }
                // Update the cache before Pass #2
                _cachedDependencyGraphSpec = dependencyGraphSpec;

                // Pass #2 For any dirty specs discrepancies, mark them and their parents as needing restore.
                var dirtyProjects = GetParents(dirtySpecs, dependencyGraphSpec);

                // All dirty projects + projects with outputs that need to be restored
                // - the projects that are non transitive that never needed restore anyways, hence the intersection with the provider restore projects!
                var resultSpecs = dirtyProjects.Union(dirtyOutputs);
                if (hasDirtyNonTransitiveSpecs)
                {
                    resultSpecs = dependencyGraphSpec.Restore.Intersect(resultSpecs);
                }

                ReplayAllWarnings(_restoreData, (string projectName) => !resultSpecs.Contains(projectName), logger);
                return(resultSpecs);
            }
            else
            {
                _cachedDependencyGraphSpec = dependencyGraphSpec;

                return(dependencyGraphSpec.Restore);
            }
        }
예제 #13
0
        private static async Task <RestoreSummary> PerformNuGetV2RestoreAsync(Common.ILogger log, DependencyGraphSpec dgFile, bool noCache, bool disableParallel, bool interactive)
        {
            string globalPackageFolder           = null;
            string repositoryPath                = null;
            string firstPackagesConfigPath       = null;
            IList <PackageSource> packageSources = null;

            var installedPackageReferences = new HashSet <Packaging.PackageReference>(new PackageReferenceComparer());

            ISettings settings = null;

            foreach (PackageSpec packageSpec in dgFile.Projects.Where(i => i.RestoreMetadata.ProjectStyle == ProjectStyle.PackagesConfig))
            {
                var pcRestoreMetadata = (PackagesConfigProjectRestoreMetadata)packageSpec.RestoreMetadata;
                globalPackageFolder = globalPackageFolder ?? pcRestoreMetadata.PackagesPath;
                repositoryPath      = repositoryPath ?? pcRestoreMetadata.RepositoryPath;

                if (packageSources == null)
                {
                    packageSources = new List <PackageSource>();
                    if (!noCache)
                    {
                        if (!string.IsNullOrEmpty(globalPackageFolder) && Directory.Exists(globalPackageFolder))
                        {
                            packageSources.Add(new FeedTypePackageSource(globalPackageFolder, FeedType.FileSystemV3));
                        }
                    }

                    packageSources.AddRange(pcRestoreMetadata.Sources);
                }

                settings = settings ?? Settings.LoadSettingsGivenConfigPaths(pcRestoreMetadata.ConfigFilePaths);

                var packagesConfigPath = Path.Combine(Path.GetDirectoryName(pcRestoreMetadata.ProjectPath), NuGetConstants.PackageReferenceFile);

                firstPackagesConfigPath = firstPackagesConfigPath ?? packagesConfigPath;

                installedPackageReferences.AddRange(GetInstalledPackageReferences(packagesConfigPath, allowDuplicatePackageIds: true));
            }

            if (string.IsNullOrEmpty(repositoryPath))
            {
                throw new InvalidOperationException(Strings.RestoreNoSolutionFound);
            }

            PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings);
            var sourceRepositoryProvider = new CachingSourceProvider(packageSourceProvider);
            var nuGetPackageManager      = new NuGetPackageManager(sourceRepositoryProvider, settings, repositoryPath);

            var effectivePackageSaveMode = CalculateEffectivePackageSaveMode(settings);

            var packageSaveMode = effectivePackageSaveMode == Packaging.PackageSaveMode.None ?
                                  Packaging.PackageSaveMode.Defaultv2 :
                                  effectivePackageSaveMode;

            var missingPackageReferences = installedPackageReferences.Where(reference =>
                                                                            !nuGetPackageManager.PackageExistsInPackagesFolder(reference.PackageIdentity, packageSaveMode)).ToArray();

            if (missingPackageReferences.Length == 0)
            {
                return(new RestoreSummary(true));
            }
            var packageRestoreData = missingPackageReferences.Select(reference =>
                                                                     new PackageRestoreData(
                                                                         reference,
                                                                         new[] { firstPackagesConfigPath },
                                                                         isMissing: true));

            var repositories = sourceRepositoryProvider.GetRepositories().ToArray();

            var installCount    = 0;
            var failedEvents    = new ConcurrentQueue <PackageRestoreFailedEventArgs>();
            var collectorLogger = new RestoreCollectorLogger(log);

            var packageRestoreContext = new PackageRestoreContext(
                nuGetPackageManager,
                packageRestoreData,
                CancellationToken.None,
                packageRestoredEvent: (sender, args) => { Interlocked.Add(ref installCount, args.Restored ? 1 : 0); },
                packageRestoreFailedEvent: (sender, args) => { failedEvents.Enqueue(args); },
                sourceRepositories: repositories,
                maxNumberOfParallelTasks: disableParallel
                    ? 1
                    : PackageManagementConstants.DefaultMaxDegreeOfParallelism,
                logger: collectorLogger);

            // TODO: Check require consent?
            // NOTE: This feature is currently not working at all. See https://github.com/NuGet/Home/issues/4327
            // CheckRequireConsent();

            var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, collectorLogger);
            var projectContext      = new ConsoleProjectContext(collectorLogger)
            {
                PackageExtractionContext = new PackageExtractionContext(
                    packageSaveMode,
                    PackageExtractionBehavior.XmlDocFileSaveMode,
                    clientPolicyContext,
                    collectorLogger)
            };

            if (effectivePackageSaveMode != Packaging.PackageSaveMode.None)
            {
                projectContext.PackageExtractionContext.PackageSaveMode = packageSaveMode;
            }

            using (var cacheContext = new SourceCacheContext())
            {
                cacheContext.NoCache = noCache;

                var packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(settings);

                var downloadContext = new PackageDownloadContext(cacheContext, repositoryPath, directDownload: false, packageSourceMapping)
                {
                    ClientPolicyContext = clientPolicyContext
                };

                DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !interactive);

                var result = await PackageRestoreManager.RestoreMissingPackagesAsync(
                    packageRestoreContext,
                    projectContext,
                    downloadContext);

                return(new RestoreSummary(
                           result.Restored,
                           "packages.config projects",
                           settings.GetConfigFilePaths().ToArray(),
                           packageSources.Select(x => x.Source).ToArray(),
                           installCount,
                           collectorLogger.Errors.Concat(ProcessFailedEventsIntoRestoreLogs(failedEvents)).ToArray()
                           ));
            }
        }
예제 #14
0
        public static async Task <bool> RestoreAsync(
            DependencyGraphSpec dependencyGraphSpec,
            bool interactive,
            bool recursive,
            bool noCache,
            bool ignoreFailedSources,
            bool disableParallel,
            bool force,
            bool forceEvaluate,
            bool hideWarningsAndErrors,
            bool restorePC,
            bool cleanupAssetsForUnsupportedProjects,
            Common.ILogger log,
            CancellationToken cancellationToken)
        {
            if (dependencyGraphSpec == null)
            {
                throw new ArgumentNullException(nameof(dependencyGraphSpec));
            }

            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }

            try
            {
                DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !interactive);

                // Set connection limit
                NetworkProtocolUtility.SetConnectionLimit();

                // Set user agent string used for network calls
#if IS_CORECLR
                UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet .NET Core MSBuild Task")
                                             .WithOSDescription(RuntimeInformation.OSDescription));
#else
                // OS description is set by default on Desktop
                UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet Desktop MSBuild Task"));
#endif

                X509TrustStore.InitializeForDotNetSdk(log);

                var restoreSummaries = new List <RestoreSummary>();
                var providerCache    = new RestoreCommandProvidersCache();

#if IS_DESKTOP
                if (restorePC && dependencyGraphSpec.Projects.Any(i => i.RestoreMetadata.ProjectStyle == ProjectStyle.PackagesConfig))
                {
                    var v2RestoreResult = await PerformNuGetV2RestoreAsync(log, dependencyGraphSpec, noCache, disableParallel, interactive);

                    restoreSummaries.Add(v2RestoreResult);

                    if (restoreSummaries.Count < 1)
                    {
                        var message = string.Format(
                            Strings.InstallCommandNothingToInstall,
                            "packages.config"
                            );

                        log.LogMinimal(message);
                    }

                    if (!v2RestoreResult.Success)
                    {
                        v2RestoreResult
                        .Errors
                        .Where(l => l.Level == LogLevel.Warning)
                        .ForEach(message =>
                        {
                            log.LogWarning(message.Message);
                        });
                    }
                }
#endif

                using (var cacheContext = new SourceCacheContext())
                {
                    cacheContext.NoCache             = noCache;
                    cacheContext.IgnoreFailedSources = ignoreFailedSources;

                    // Pre-loaded request provider containing the graph file
                    var providers = new List <IPreLoadedRestoreRequestProvider>();

                    if (dependencyGraphSpec.Restore.Count > 0)
                    {
                        // Add all child projects
                        if (recursive)
                        {
                            AddAllProjectsForRestore(dependencyGraphSpec);
                        }

                        providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dependencyGraphSpec));

                        var restoreContext = new RestoreArgs()
                        {
                            CacheContext    = cacheContext,
                            LockFileVersion = LockFileFormat.Version,
                            // 'dotnet restore' fails on slow machines (https://github.com/NuGet/Home/issues/6742)
                            // The workaround is to pass the '--disable-parallel' option.
                            // We apply the workaround by default when the system has 1 cpu.
                            // This will fix restore failures on VMs with 1 CPU and containers with less or equal to 1 CPU assigned.
                            DisableParallel           = Environment.ProcessorCount == 1 ? true : disableParallel,
                            Log                       = log,
                            MachineWideSettings       = new XPlatMachineWideSetting(),
                            PreLoadedRequestProviders = providers,
                            AllowNoOp                 = !force,
                            HideWarningsAndErrors     = hideWarningsAndErrors,
                            RestoreForceEvaluate      = forceEvaluate
                        };

                        if (restoreContext.DisableParallel)
                        {
                            HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore();
                        }

                        cancellationToken.ThrowIfCancellationRequested();

                        restoreSummaries.AddRange(await RestoreRunner.RunAsync(restoreContext, cancellationToken));
                    }

                    if (cleanupAssetsForUnsupportedProjects)
                    {
                        // Restore assets are normally left on disk between restores for all projects.  This can cause a condition where a project that supports PackageReference was restored
                        // but then a user changes a branch or some other condition and now the project does not use PackageReference. Since the restore assets are left on disk, the build
                        // consumes them which can cause build errors. The code below cleans up all of the files that we write so that they are not used during build
                        Parallel.ForEach(dependencyGraphSpec.Projects.Where(i => !DoesProjectSupportRestore(i)), project =>
                        {
                            if (project.RestoreMetadata == null || string.IsNullOrWhiteSpace(project.RestoreMetadata.OutputPath) || string.IsNullOrWhiteSpace(project.RestoreMetadata.ProjectPath))
                            {
                                return;
                            }

                            // project.assets.json
                            FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, LockFileFormat.AssetsFileName));

                            // project.csproj.nuget.cache
                            FileUtility.Delete(project.RestoreMetadata.CacheFilePath);

                            // project.csproj.nuget.g.props
                            FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.PropsExtension));

                            // project..csproj.nuget.g.targets
                            FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.TargetsExtension));

                            // project.csproj.nuget.dgspec.json
                            FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, DependencyGraphSpec.GetDGSpecFileName(Path.GetFileName(project.RestoreMetadata.ProjectPath))));
                        });
                    }
                }

                if (restoreSummaries.Count < 1)
                {
                    log.LogMinimal(Strings.NoProjectsToRestore);
                }
                else
                {
                    RestoreSummary.Log(log, restoreSummaries);
                }
                return(restoreSummaries.All(x => x.Success));
            }
            finally
            {
                // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger.
                // We need to update the delegating logger with a null instance
                // because the tear downs of the plugins and similar rely on idleness and process exit.
                DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance);
            }
        }
예제 #15
0
 public static void NormalizePathCasings(Dictionary <string, string> paths, DependencyGraphSpec graphSpec)
 {
     NormalizePathCasings((IDictionary <string, string>)paths, graphSpec);
 }
        public async Task DotnetCliTool_BasicToolRestore_DifferentVersionRanges()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                var logger = new TestLogger();
                var dgFile = new DependencyGraphSpec();

                var versions = new List <VersionRange>();

                var limit = 100;

                for (int i = 0; i < limit; i++)
                {
                    var version = VersionRange.Parse($"{i + 1}.0.0");
                    versions.Add(version);

                    var spec = ToolRestoreUtility.GetSpec(
                        Path.Combine(pathContext.SolutionRoot, $"fake{i}.csproj"),
                        "a",
                        version,
                        NuGetFramework.Parse("netcoreapp1.0"),
                        pathContext.UserPackagesFolder,
                        new List <string>()
                    {
                        pathContext.FallbackFolder
                    },
                        new List <PackageSource>()
                    {
                        new PackageSource(pathContext.PackageSource)
                    },
                        projectWideWarningProperties: null);

                    dgFile.AddProject(spec);
                    dgFile.AddRestore(spec.Name);
                }

                var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder);

                foreach (var version in versions)
                {
                    await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, new PackageIdentity("a", version.MinVersion));
                }

                // Act
                var results = await CommandsTestUtility.RunRestore(dgFile, pathContext, logger);

                // Assert
                Assert.Equal(limit, results.Count);

                foreach (var result in results)
                {
                    Assert.True(result.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                }

                foreach (var version in versions)
                {
                    var path = pathResolver.GetLockFilePath(
                        "a",
                        version.MinVersion,
                        NuGetFramework.Parse("netcoreapp1.0"));

                    Assert.True(File.Exists(path), $"{path} does not exist!");
                }
            }
        }
예제 #17
0
        /// <summary>
        /// Returns the closure of project references for projects specified in <paramref name="projectPaths"/>.
        /// </summary>
        public static async Task <DependencyGraphSpec> GetProjectReferencesAsync(
            MsBuildToolset msbuildToolset,
            string[] projectPaths,
            int timeOut,
            IConsole console,
            bool recursive,
            string solutionDirectory,
            string solutionName,
            string restoreConfigFile,
            string[] sources,
            string packagesDirectory,
            RestoreLockProperties restoreLockProperties)
        {
            var msbuildPath = GetMsbuild(msbuildToolset.Path);

            if (!File.Exists(msbuildPath))
            {
                throw new CommandException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              LocalizedResourceManager.GetString(nameof(NuGetResources.MsBuildDoesNotExistAtPath)),
                              msbuildPath));
            }

            var nugetExePath = Assembly.GetEntryAssembly().Location;

            // Check for the non-ILMerged path
            var buildTasksPath = Path.Combine(Path.GetDirectoryName(nugetExePath), "NuGet.Build.Tasks.dll");

            if (File.Exists(buildTasksPath))
            {
                nugetExePath = buildTasksPath;
            }

            using (var inputTargetPath = new TempFile(".nugetinputs.targets"))
                using (var entryPointTargetPath = new TempFile(".nugetrestore.targets"))
                    using (var resultsPath = new TempFile(".output.dg"))
                    {
                        // Read NuGet.targets from nuget.exe and write it to disk for msbuild.exe
                        ExtractResource(NuGetTargets, entryPointTargetPath);

                        // Build a .targets file of all restore inputs, this is needed to avoid going over the limit on command line arguments.
                        var properties = new Dictionary <string, string>()
                        {
                            { "RestoreUseCustomAfterTargets", "true" },
                            { "RestoreGraphOutputPath", resultsPath },
                            { "RestoreRecursive", recursive.ToString().ToLowerInvariant() },
                            { "RestoreProjectFilterMode", "exclusionlist" }
                        };

                        var inputTargetXML = GetRestoreInputFile(entryPointTargetPath, properties, projectPaths);

                        inputTargetXML.Save(inputTargetPath);

                        // Create msbuild parameters and include global properties that cannot be set in the input targets path
                        var arguments = GetMSBuildArguments(entryPointTargetPath, inputTargetPath, nugetExePath, solutionDirectory, solutionName, restoreConfigFile, sources, packagesDirectory, msbuildToolset, restoreLockProperties, EnvironmentVariableWrapper.Instance);

                        var processStartInfo = new ProcessStartInfo
                        {
                            UseShellExecute        = false,
                            FileName               = msbuildPath,
                            Arguments              = arguments,
                            RedirectStandardError  = true,
                            RedirectStandardOutput = true
                        };

                        console.LogDebug($"{processStartInfo.FileName} {processStartInfo.Arguments}");

                        using (var process = Process.Start(processStartInfo))
                        {
                            var errors   = new StringBuilder();
                            var output   = new StringBuilder();
                            var excluded = new string[] { "msb4011", entryPointTargetPath };

                            // Read console output
                            var errorTask  = ConsumeStreamReaderAsync(process.StandardError, errors, filter: null);
                            var outputTask = ConsumeStreamReaderAsync(process.StandardOutput, output, filter: (line) => IsIgnoredOutput(line, excluded));

                            // Run msbuild
                            var finished = process.WaitForExit(timeOut);

                            // Handle timeouts
                            if (!finished)
                            {
                                try
                                {
                                    process.Kill();
                                }
                                catch (Exception ex)
                                {
                                    throw new CommandException(
                                              LocalizedResourceManager.GetString(nameof(NuGetResources.Error_CannotKillMsBuild)) + " : " +
                                              ex.Message,
                                              ex);
                                }
                            }

                            // Read all console output from msbuild.
                            await Task.WhenAll(outputTask, errorTask);

                            // By default log msbuild output so that it is only
                            // displayed under -Verbosity detailed
                            var logLevel = LogLevel.Verbose;

                            if (process.ExitCode != 0 || !finished)
                            {
                                // If a problem occurred log all msbuild output as an error
                                // so that the user can see it.
                                // By default this runs with /v:q which means that only
                                // errors and warnings will be in the output.
                                logLevel = LogLevel.Error;
                            }

                            // MSBuild writes errors to the output stream, parsing the console output to find
                            // the errors would be error prone so here we log all output combined with any
                            // errors on the error stream (haven't seen the error stream used to date)
                            // to give the user the complete info.
                            await console.LogAsync(logLevel, output.ToString() + errors.ToString());

                            if (!finished)
                            {
                                // MSBuild timed out
                                throw new CommandException(
                                          LocalizedResourceManager.GetString(nameof(NuGetResources.Error_MsBuildTimedOut)));
                            }

                            await outputTask;

                            if (process.ExitCode != 0)
                            {
                                // Do not continue if msbuild failed.
                                throw new ExitCodeException(1);
                            }
                        }

                        DependencyGraphSpec spec = null;

                        if (File.Exists(resultsPath) && new FileInfo(resultsPath).Length != 0)
                        {
                            spec = DependencyGraphSpec.Load(resultsPath);
                            File.Delete(resultsPath);
                        }
                        else
                        {
                            spec = new DependencyGraphSpec();
                        }

                        return(spec);
                    }
        }
예제 #18
0
        public async Task RestoreRunner_BasicRestore_VerifyFailureWritesFiles_NETCore()
        {
            // Arrange
            var sources = new List <PackageSource>();

            var project1Json = @"
            {
              ""version"": ""1.0.0"",
              ""description"": """",
              ""authors"": [ ""author"" ],
              ""tags"": [ """" ],
              ""projectUrl"": """",
              ""licenseUrl"": """",
              ""frameworks"": {
                ""net45"": {
                    ""dependencies"": {
                        ""x"": ""1.0.0""
                    }
                }
              }
            }";

            using (var workingDir = TestDirectory.Create())
            {
                var packagesDir   = new DirectoryInfo(Path.Combine(workingDir, "globalPackages"));
                var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource"));
                var project1      = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1"));
                packagesDir.Create();
                packageSource.Create();
                project1.Create();
                sources.Add(new PackageSource(packageSource.FullName));

                File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json);

                var specPath1 = Path.Combine(project1.FullName, "project.json");
                var spec1     = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1);
                spec1.RestoreMetadata                   = new ProjectRestoreMetadata();
                spec1.RestoreMetadata.OutputPath        = Path.Combine(project1.FullName, "obj");
                spec1.RestoreMetadata.ProjectStyle      = ProjectStyle.PackageReference;
                spec1.RestoreMetadata.ProjectName       = "project1";
                spec1.RestoreMetadata.ProjectPath       = Path.Combine(project1.FullName, "project1.csproj");
                spec1.RestoreMetadata.ProjectUniqueName = spec1.RestoreMetadata.ProjectPath;
                spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45")));
                spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45");
                spec1.FilePath = spec1.RestoreMetadata.ProjectPath;

                var dgSpec = new DependencyGraphSpec();
                dgSpec.AddProject(spec1);
                dgSpec.AddRestore(spec1.RestoreMetadata.ProjectUniqueName);

                var logger     = new TestLogger();
                var assetsPath = Path.Combine(project1.FullName, "obj", "project.assets.json");

                var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList();

                var providerCache = new RestoreCommandProvidersCache();

                using (var cacheContext = new SourceCacheContext())
                {
                    var restoreContext = new RestoreArgs()
                    {
                        CacheContext         = cacheContext,
                        DisableParallel      = true,
                        GlobalPackagesFolder = packagesDir.FullName,
                        Sources = new List <string>()
                        {
                            packageSource.FullName
                        },
                        Log = logger,
                        CachingSourceProvider     = new CachingSourceProvider(new TestPackageSourceProvider(sources)),
                        PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>()
                        {
                            new DependencyGraphSpecRequestProvider(providerCache, dgSpec)
                        }
                    };

                    // Act
                    var summaries = await RestoreRunner.Run(restoreContext);

                    var summary = summaries.Single();

                    // Assert
                    Assert.False(summary.Success);
                    Assert.True(File.Exists(assetsPath), assetsPath);
                    Assert.True(File.Exists(Path.Combine(project1.FullName, "obj", "project1.csproj.nuget.g.props")));
                    Assert.True(File.Exists(Path.Combine(project1.FullName, "obj", "project1.csproj.nuget.g.targets")));
                }
            }
        }
예제 #19
0
 public PackageRestoreInputs()
 {
     ProjectReferenceLookup = new DependencyGraphSpec();
 }
예제 #20
0
        public async Task RestoreRunner_RestoreWithExternalFile_NetCoreOutput()
        {
            // Arrange
            var sources = new List <PackageSource>();

            var targetFrameworkInfo1 = new TargetFrameworkInformation();

            targetFrameworkInfo1.FrameworkName = NuGetFramework.Parse("net45");
            var frameworks1 = new[] { targetFrameworkInfo1 };

            var targetFrameworkInfo2 = new TargetFrameworkInformation();

            targetFrameworkInfo2.FrameworkName = NuGetFramework.Parse("net45");
            var frameworks2 = new[] { targetFrameworkInfo2 };

            // Create two net45 projects
            var spec1 = new PackageSpec(frameworks1);

            spec1.RestoreMetadata = new ProjectRestoreMetadata();
            spec1.RestoreMetadata.ProjectUniqueName = "project1";
            spec1.RestoreMetadata.ProjectName       = "project1";
            spec1.RestoreMetadata.ProjectStyle      = ProjectStyle.PackageReference;
            spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45");

            var spec2 = new PackageSpec(frameworks2);

            spec2.RestoreMetadata = new ProjectRestoreMetadata();
            spec2.RestoreMetadata.ProjectUniqueName = "project2";
            spec2.RestoreMetadata.ProjectName       = "project2";
            spec2.RestoreMetadata.ProjectStyle      = ProjectStyle.PackageReference;
            spec2.RestoreMetadata.OriginalTargetFrameworks.Add("net45");

            var specs = new[] { spec1, spec2 };

            using (var workingDir = TestDirectory.Create())
            {
                var packagesDir   = new DirectoryInfo(Path.Combine(workingDir, "globalPackages"));
                var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource"));
                var project1      = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1"));
                var project2      = new DirectoryInfo(Path.Combine(workingDir, "projects", "project2"));
                packagesDir.Create();
                packageSource.Create();
                project1.Create();
                project2.Create();
                sources.Add(new PackageSource(packageSource.FullName));

                var projPath1 = Path.Combine(project1.FullName, "project1.csproj");
                var projPath2 = Path.Combine(project2.FullName, "project2.csproj");
                File.WriteAllText(projPath1, string.Empty);
                File.WriteAllText(projPath2, string.Empty);

                spec1.RestoreMetadata.ProjectPath = projPath1;
                spec1.FilePath = projPath1;
                spec1.Name     = "project1";
                spec2.RestoreMetadata.ProjectPath = projPath2;
                spec2.FilePath = projPath1;
                spec2.Name     = "project2";

                var logger   = new TestLogger();
                var objPath1 = Path.Combine(project1.FullName, "obj");
                var objPath2 = Path.Combine(project2.FullName, "obj");

                spec1.RestoreMetadata.OutputPath = objPath1;
                spec2.RestoreMetadata.OutputPath = objPath2;

                spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45");
                spec2.RestoreMetadata.OriginalTargetFrameworks.Add("net45");

                var lockPath1 = Path.Combine(objPath1, "project.assets.json");
                var lockPath2 = Path.Combine(objPath2, "project.assets.json");

                // Link projects
                spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency()
                {
                    LibraryRange = new LibraryRange()
                    {
                        Name           = "project2",
                        TypeConstraint = LibraryDependencyTarget.ExternalProject
                    }
                });

                spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45")));
                spec1.RestoreMetadata.TargetFrameworks
                .Single()
                .ProjectReferences
                .Add(new ProjectRestoreReference()
                {
                    ProjectPath       = projPath2,
                    ProjectUniqueName = "project2"
                });

                // Create dg file
                var dgFile = new DependencyGraphSpec();

                foreach (var spec in specs)
                {
                    dgFile.AddRestore(spec.RestoreMetadata.ProjectName);
                    dgFile.AddProject(spec);
                }

                var dgPath = Path.Combine(workingDir, "input.dg");
                dgFile.Save(dgPath);

                var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList();

                var providerCache = new RestoreCommandProvidersCache();

                using (var cacheContext = new SourceCacheContext())
                {
                    var restoreContext = new RestoreArgs()
                    {
                        CacheContext         = cacheContext,
                        DisableParallel      = true,
                        GlobalPackagesFolder = packagesDir.FullName,
                        Sources = new List <string>()
                        {
                            packageSource.FullName
                        },
                        Inputs = new List <string>()
                        {
                            dgPath
                        },
                        Log = logger,
                        CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)),
                        RequestProviders      = new List <IRestoreRequestProvider>()
                        {
                            new DependencyGraphFileRequestProvider(providerCache)
                        }
                    };

                    // Act
                    var summaries = await RestoreRunner.Run(restoreContext);

                    var success = summaries.All(s => s.Success);

                    var lockFormat  = new LockFileFormat();
                    var lockFile1   = lockFormat.Read(lockPath1);
                    var project2Lib = lockFile1.Libraries.First();

                    // Assert
                    Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                    Assert.True(File.Exists(lockPath1), lockPath1);
                    Assert.True(File.Exists(lockPath2), lockPath2);
                    Assert.Equal("project2", project2Lib.Name);
                }
            }
        }
예제 #21
0
        private static async Task <RestoreResultPair> PreviewAddPackageReferenceAsync(PackageReferenceArgs packageReferenceArgs,
                                                                                      DependencyGraphSpec dgSpec)
        {
            // Set user agent and connection settings.
            XPlatUtility.ConfigureProtocol();

            var providerCache = new RestoreCommandProvidersCache();

            using (var cacheContext = new SourceCacheContext())
            {
                cacheContext.NoCache             = false;
                cacheContext.IgnoreFailedSources = false;

                // Pre-loaded request provider containing the graph file
                var providers = new List <IPreLoadedRestoreRequestProvider>
                {
                    new DependencyGraphSpecRequestProvider(providerCache, dgSpec)
                };

                var restoreContext = new RestoreArgs()
                {
                    CacheContext              = cacheContext,
                    LockFileVersion           = LockFileFormat.Version,
                    Log                       = packageReferenceArgs.Logger,
                    MachineWideSettings       = new XPlatMachineWideSetting(),
                    GlobalPackagesFolder      = packageReferenceArgs.PackageDirectory,
                    PreLoadedRequestProviders = providers,
                    Sources                   = packageReferenceArgs.Sources?.ToList()
                };

                // Generate Restore Requests. There will always be 1 request here since we are restoring for 1 project.
                var restoreRequests = await RestoreRunner.GetRequests(restoreContext);

                //Setup the Credential Service
                DefaultCredentialServiceUtility.SetupDefaultCredentialService(restoreContext.Log, !packageReferenceArgs.Interactive);

                // Run restore without commit. This will always return 1 Result pair since we are restoring for 1 request.
                var restoreResult = await RestoreRunner.RunWithoutCommit(restoreRequests, restoreContext);

                return(restoreResult.Single());
            }
        }
예제 #22
0
        public async Task ContentFilesMSBuild_VerifyConditionForFallbackContentItemGroup(string files, string expected)
        {
            // Arrange
            var logger = new TestLogger();

            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var tfi = new List <TargetFrameworkInformation>
                    {
                        new TargetFrameworkInformation()
                        {
                            FrameworkName = NuGetFramework.Parse("net462")
                        }
                    };

                    var spec = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "net46");
                    spec.Dependencies.Add(new LibraryDependency()
                    {
                        LibraryRange = new LibraryRange("a", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package)
                    });

                    var project = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, spec).Single();

                    var packageA = new SimpleTestPackageContext("a");
                    packageA.AddFile("contentFiles/any/any/anyMarker.txt");

                    foreach (var file in files.Split('|'))
                    {
                        packageA.AddFile(file);
                    }

                    SimpleTestPackageUtility.CreatePackages(pathContext.PackageSource, packageA);

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();
                    dgFile.AddProject(spec);
                    dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName);

                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    // Act
                    var result = (await NETCoreRestoreTestUtility.RunRestore(
                                      pathContext,
                                      logger,
                                      new List <PackageSource>()
                    {
                        new PackageSource(pathContext.PackageSource)
                    },
                                      dgFile,
                                      cacheContext)).Single();

                    var props      = XDocument.Load(project.PropsOutput);
                    var itemGroups = props.Root.Elements(XName.Get("ItemGroup", "http://schemas.microsoft.com/developer/msbuild/2003")).ToArray();
                    var group      = itemGroups.Single(e => e.ToString().Contains("anyMarker.txt"));

                    // Assert
                    Assert.True(result.Success, logger.ShowErrors());
                    Assert.Equal(expected.Trim(), group.Attribute(XName.Get("Condition")).Value.Trim());
                }
        }
        /// <summary>
        /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json).
        /// </summary>
        /// <param name="libraryIdentity">The <see cref="LibraryIdentity"/> of the package.</param>
        /// <param name="settings">The NuGet settings to use.</param>
        /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param>
        /// <returns></returns>
        public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(LibraryIdentity libraryIdentity, ISettings settings, ILogger logger)
        {
            using (var sourceCacheContext = new SourceCacheContext
            {
                IgnoreFailedSources = true,
            })
            {
                var projectDirectory = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N"));

                var projectName = Guid.NewGuid().ToString("N");

                var projectFullPath = Path.Combine(projectDirectory, $"{projectName}.proj");

                // Iterate through TargetFrameworks to generate Lists required for packageSpec
                var frameworks = new List <TargetFrameworkInformation>(TargetFrameworks.Count);
                var originalTargetFrameworks = new List <string>(TargetFrameworks.Count);
                foreach (var tf in TargetFrameworks)
                {
                    frameworks.Add(new TargetFrameworkInformation
                    {
                        FrameworkName = tf
                    });

                    originalTargetFrameworks.Add(tf.ToString());
                }

                // The package spec details what packages to restore
                var packageSpec = new PackageSpec(frameworks)
                {
                    Dependencies = new List <LibraryDependency>
                    {
                        new LibraryDependency
                        {
                            LibraryRange = new LibraryRange(
                                libraryIdentity.Name,
                                new VersionRange(
                                    minVersion: libraryIdentity.Version,
                                    includeMinVersion: true,
                                    maxVersion: libraryIdentity.Version,
                                    includeMaxVersion: true),
                                LibraryDependencyTarget.Package),
                            SuppressParent = LibraryIncludeFlags.All,
                            AutoReferenced = true,
                            IncludeType    = LibraryIncludeFlags.None,
                        }
                    },
                    RestoreMetadata = new ProjectRestoreMetadata
                    {
                        ProjectPath              = projectFullPath,
                        ProjectName              = projectName,
                        ProjectStyle             = ProjectStyle.PackageReference,
                        ProjectUniqueName        = projectFullPath,
                        OutputPath               = projectDirectory,
                        OriginalTargetFrameworks = originalTargetFrameworks,
                        ConfigFilePaths          = settings.GetConfigFilePaths(),
                        PackagesPath             = SettingsUtility.GetGlobalPackagesFolder(settings),
                        Sources         = SettingsUtility.GetEnabledSources(settings).AsList(),
                        FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                    },
                    FilePath = projectFullPath,
                    Name     = projectName,
                };

                var dependencyGraphSpec = new DependencyGraphSpec();

                dependencyGraphSpec.AddProject(packageSpec);

                dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);

                IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                var restoreArgs = new RestoreArgs
                {
                    AllowNoOp    = false,
                    CacheContext = sourceCacheContext,
#pragma warning disable CS0618 // Type or member is obsolete
                    CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)),
#pragma warning restore CS0618 // Type or member is obsolete
                    Log = logger,
                };

                // Create requests from the arguments
                var requests = requestProvider.CreateRequests(restoreArgs).Result;

                // Restore the package without generating extra files
                return(RestoreRunner.RunWithoutCommit(requests, restoreArgs));
            }
        }
        public void GetParents_WithMultiLevelGraph_WhenALeafIsDirty_ReturnsProjectsFromEveryLevelAsDirty()
        {
            var projectA = GetPackageSpec("A");
            var projectB = GetPackageSpec("B");
            var projectC = GetPackageSpec("C");
            var projectD = GetPackageSpec("D");
            var projectE = GetPackageSpec("E");
            var projectF = GetPackageSpec("F");
            var projectG = GetPackageSpec("G");
            var projectH = GetPackageSpec("H");
            var projectI = GetPackageSpec("I");
            var projectJ = GetPackageSpec("J");
            var projectK = GetPackageSpec("K");
            var projectL = GetPackageSpec("L");
            var projectM = GetPackageSpec("M");

            // A => B & C
            projectA = projectA.WithTestProjectReference(projectB).WithTestProjectReference(projectC);
            // B => D
            projectB = projectB.WithTestProjectReference(projectD);
            // D => F
            projectD = projectD.WithTestProjectReference(projectF);
            // C => E
            projectC = projectC.WithTestProjectReference(projectE);
            // G => D
            projectG = projectG.WithTestProjectReference(projectD);
            // H => C
            projectH = projectH.WithTestProjectReference(projectC);
            // I => F
            projectI = projectI.WithTestProjectReference(projectF);
            // H => I
            projectH = projectH.WithTestProjectReference(projectI);
            // K => L
            projectK = projectK.WithTestProjectReference(projectL);
            // J => K
            projectJ = projectJ.WithTestProjectReference(projectK);
            // H => J
            projectH = projectH.WithTestProjectReference(projectJ);
            // M => L
            projectM = projectM.WithTestProjectReference(projectL);


            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddProject(projectA);
            dgSpec.AddRestore(projectA.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectB);
            dgSpec.AddRestore(projectB.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectC);
            dgSpec.AddRestore(projectC.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectD);
            dgSpec.AddRestore(projectD.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectE);
            dgSpec.AddRestore(projectE.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectF);
            dgSpec.AddRestore(projectF.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectG);
            dgSpec.AddRestore(projectG.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectH);
            dgSpec.AddRestore(projectH.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectI);
            dgSpec.AddRestore(projectI.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectJ);
            dgSpec.AddRestore(projectJ.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectK);
            dgSpec.AddRestore(projectK.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectL);
            dgSpec.AddRestore(projectL.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectM);
            dgSpec.AddRestore(projectM.RestoreMetadata.ProjectUniqueName);

            var expected = GetUniqueNames(projectA, projectC, projectE, projectH, projectJ, projectK, projectL, projectM);
            var actual   = SolutionUpToDateChecker.GetParents(GetUniqueNames(projectE, projectL), dgSpec);

            actual.Should().BeEquivalentTo(expected);
        }
예제 #25
0
        public void Json_WhenDgSpecWasCreatedWithDefaultConstructor_ReturnsEmptyObject()
        {
            var dgSpec = new DependencyGraphSpec();

            Assert.Empty(dgSpec.Json);
        }
        public static async Task <(DependencyGraphSpec dgSpec, IReadOnlyList <IAssetsLogMessage> additionalMessages)> GetSolutionRestoreSpecAndAdditionalMessages(
            ISolutionManager solutionManager,
            DependencyGraphCacheContext context)
        {
            var dgSpec = new DependencyGraphSpec();
            List <IAssetsLogMessage> allAdditionalMessages = null;

            var projects      = (await solutionManager.GetNuGetProjectsAsync()).OfType <IDependencyGraphProject>().ToList();
            var knownProjects = projects.Select(e => e.MSBuildProjectPath).ToHashSet(PathUtility.GetStringComparerBasedOnOS());

            for (var i = 0; i < projects.Count; i++)
            {
                var(packageSpecs, projectAdditionalMessages) = await projects[i].GetPackageSpecsAndAdditionalMessagesAsync(context);

                if (projectAdditionalMessages != null && projectAdditionalMessages.Count > 0)
                {
                    if (allAdditionalMessages == null)
                    {
                        allAdditionalMessages = new List <IAssetsLogMessage>();
                    }

                    allAdditionalMessages.AddRange(projectAdditionalMessages);
                }

                foreach (var packageSpec in packageSpecs)
                {
                    dgSpec.AddProject(packageSpec);

                    if (packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                        packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ||
                        packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool ||
                        packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone) // Don't add global tools to restore specs for solutions
                    {
                        dgSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);

                        var projFileName = Path.GetFileName(packageSpec.RestoreMetadata.ProjectPath);
                        var dgFileName   = DependencyGraphSpec.GetDGSpecFileName(projFileName);
                        var outputPath   = packageSpec.RestoreMetadata.OutputPath;

                        if (!string.IsNullOrEmpty(outputPath))
                        {
                            for (int frameworkCount = 0; frameworkCount < packageSpec.RestoreMetadata.TargetFrameworks.Count; frameworkCount++)
                            {
                                for (var projectReferenceCount = 0; projectReferenceCount < packageSpec.RestoreMetadata.TargetFrameworks[frameworkCount].ProjectReferences.Count; projectReferenceCount++)
                                {
                                    if (!knownProjects.Contains(packageSpec.RestoreMetadata.TargetFrameworks[frameworkCount].ProjectReferences[projectReferenceCount].ProjectPath))
                                    {
                                        var persistedDGSpecPath = Path.Combine(outputPath, dgFileName);
                                        if (File.Exists(persistedDGSpecPath))
                                        {
                                            var persistedDGSpec = DependencyGraphSpec.Load(persistedDGSpecPath);
                                            foreach (var dependentPackageSpec in persistedDGSpec.Projects.Where(e => !knownProjects.Contains(e.RestoreMetadata.ProjectPath)))
                                            {
                                                // Include all the missing projects from the closure.
                                                // Figuring out exactly what we need would be too and an overkill. That will happen later in the DependencyGraphSpecRequestProvider
                                                knownProjects.Add(dependentPackageSpec.RestoreMetadata.ProjectPath);
                                                dgSpec.AddProject(dependentPackageSpec);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Return dg file
            return(dgSpec, allAdditionalMessages);
        }
예제 #27
0
        public void AddProject_WhenDependencyVersionIsNull_CentralPackageVersionAppliesOnlyWhenAutoReferencedIsFalse()
        {
            // Arrange
            var dependencyFoo = new LibraryDependency(
                new LibraryRange("foo", versionRange: null, LibraryDependencyTarget.Package),
                LibraryDependencyType.Default,
                LibraryIncludeFlags.All,
                LibraryIncludeFlags.All,
                new List <Common.NuGetLogCode>(),
                autoReferenced: false,
                generatePathProperty: true,
                versionCentrallyManaged: false,
                LibraryDependencyReferenceType.Direct,
                aliases: null);
            var dependencyBar = new LibraryDependency(
                new LibraryRange("bar", VersionRange.Parse("3.0.0"), LibraryDependencyTarget.Package),
                LibraryDependencyType.Default,
                LibraryIncludeFlags.All,
                LibraryIncludeFlags.All,
                new List <Common.NuGetLogCode>(),
                autoReferenced: true,
                generatePathProperty: true,
                versionCentrallyManaged: false,
                LibraryDependencyReferenceType.Direct,
                aliases: null);
            var dependencyBoom = new LibraryDependency(
                new LibraryRange("boom", versionRange: null, LibraryDependencyTarget.Package),
                LibraryDependencyType.Default,
                LibraryIncludeFlags.All,
                LibraryIncludeFlags.All,
                new List <Common.NuGetLogCode>(),
                autoReferenced: true,
                generatePathProperty: true,
                versionCentrallyManaged: false,
                LibraryDependencyReferenceType.Direct,
                aliases: null);
            var centralVersionFoo  = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0"));
            var centralVersionBar  = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0"));
            var centralVersionBoom = new CentralPackageVersion("boom", VersionRange.Parse("4.0.0"));

            var tfi = CreateTargetFrameworkInformation(
                new List <LibraryDependency>()
            {
                dependencyFoo, dependencyBar, dependencyBoom
            },
                new List <CentralPackageVersion>()
            {
                centralVersionFoo, centralVersionBar, centralVersionBoom
            });

            // Act
            DependencyGraphSpec dependencyGraphSpec = CreateDependencyGraphSpecWithCentralDependencies(tfi);

            // Assert
            Assert.Equal(1, dependencyGraphSpec.Projects.Count);
            PackageSpec packSpec = dependencyGraphSpec.Projects[0];
            IList <TargetFrameworkInformation> tfms         = packSpec.TargetFrameworks;
            IList <LibraryDependency>          dependencies = tfms[0].Dependencies;

            Assert.Equal(1, tfms.Count);
            Assert.Equal(3, dependencies.Count);
            Assert.Equal("[1.0.0, )", dependencies.Where(d => d.Name == "foo").First().LibraryRange.VersionRange.ToNormalizedString());
            Assert.True(dependencies.Where(d => d.Name == "foo").First().VersionCentrallyManaged);
            Assert.Equal("[3.0.0, )", dependencies.Where(d => d.Name == "bar").First().LibraryRange.VersionRange.ToNormalizedString());
            Assert.False(dependencies.Where(d => d.Name == "bar").First().VersionCentrallyManaged);
            Assert.Null(dependencies.Where(d => d.Name == "boom").First().LibraryRange.VersionRange);
        }
        public async Task GetInstallActionsAsync_WithProjectReferenceProject_WhenUpdatingPackage_ReturnsCorrectActions()
        {
            const string projectName        = "a";
            string       projectId          = Guid.NewGuid().ToString();
            var          projectSystemCache = new ProjectSystemCache();

            using (TestDirectory testDirectory = TestDirectory.Create())
            {
                var    packageV1 = new SimpleTestPackageContext(packageId: "b", version: "1.0.0");
                var    packageV2 = new SimpleTestPackageContext(packageV1.Id, version: "2.0.0");
                string packageSourceDirectoryPath = Path.Combine(testDirectory, "packageSource");

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(
                    packageSourceDirectoryPath,
                    PackageSaveMode.Defaultv3,
                    packageV1,
                    packageV2);

                var packageSource  = new PackageSource(packageSourceDirectoryPath);
                var packageSources = new List <PackageSource>()
                {
                    packageSource
                };

                Initialize(packageSources);

                string projectFullPath          = Path.Combine(testDirectory.Path, $"{projectName}.csproj");
                var    unconfiguredProject      = new Mock <UnconfiguredProject>();
                var    configuredProject        = new Mock <ConfiguredProject>();
                var    projectServices          = new Mock <ConfiguredProjectServices>();
                var    packageReferencesService = new Mock <IPackageReferencesService>();
                var    result = new Mock <IUnresolvedPackageReference>();

                unconfiguredProject.Setup(x => x.GetSuggestedConfiguredProjectAsync())
                .ReturnsAsync(configuredProject.Object);

                configuredProject.SetupGet(x => x.Services)
                .Returns(projectServices.Object);

                projectServices.SetupGet(x => x.PackageReferences)
                .Returns(packageReferencesService.Object);

                packageReferencesService.Setup(x => x.AddAsync(It.IsNotNull <string>(), It.IsNotNull <string>()))
                .ReturnsAsync(new AddReferenceResult <IUnresolvedPackageReference>(result.Object, added: true));

                var nuGetProjectServices = new Mock <INuGetProjectServices>();

                nuGetProjectServices.SetupGet(x => x.ScriptService)
                .Returns(Mock.Of <IProjectScriptHostService>());

                var project = new CpsPackageReferenceProject(
                    projectName: projectName,
                    projectUniqueName: projectFullPath,
                    projectFullPath: projectFullPath,
                    projectSystemCache,
                    unconfiguredProject.Object,
                    nuGetProjectServices.Object,
                    projectId);

                PackageSpec packageSpec = CreatePackageSpec(
                    project.ProjectName,
                    Path.Combine(testDirectory, "package.spec"));
                DependencyGraphSpec projectRestoreInfo = ProjectJsonTestHelpers.GetDGSpecFromPackageSpecs(packageSpec);
                projectRestoreInfo.AddProject(packageSpec);
                var projectNames = new ProjectNames(
                    fullName: projectFullPath,
                    uniqueName: projectFullPath,
                    shortName: projectName,
                    customUniqueName: projectName,
                    projectId: projectId);
                projectSystemCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, Array.Empty <IAssetsLogMessage>());

                _solutionManager.NuGetProjects.Add(project);

                string[] projectIds         = new[] { projectId };
                string[] packageSourceNames = new[] { packageSource.Name };

                await PerformOperationAsync(async (projectManager) =>
                {
                    IReadOnlyList <ProjectAction> actions = await projectManager.GetInstallActionsAsync(
                        projectIds,
                        packageV1.Identity,
                        VersionConstraints.None,
                        includePrelease: true,
                        DependencyBehavior.Lowest,
                        packageSourceNames,
                        CancellationToken.None);

                    Assert.NotEmpty(actions);
                    Assert.Equal(1, actions.Count);

                    ProjectAction action = actions[0];

                    Assert.Equal(packageV1.Identity, action.PackageIdentity);
                    Assert.Equal(NuGetProjectActionType.Install, action.ProjectActionType);
                    Assert.Equal(projectId, action.ProjectId);

                    Assert.Equal(1, action.ImplicitActions.Count);

                    ImplicitProjectAction implicitAction = action.ImplicitActions[0];

                    Assert.Equal(packageV1.Identity, implicitAction.PackageIdentity);
                    Assert.Equal(NuGetProjectActionType.Install, implicitAction.ProjectActionType);

                    await projectManager.ExecuteActionsAsync(actions, CancellationToken.None);
                });

                await PerformOperationAsync(async (projectManager) =>
                {
                    IReadOnlyList <ProjectAction> actions = await projectManager.GetInstallActionsAsync(
                        projectIds,
                        packageV2.Identity,
                        VersionConstraints.None,
                        includePrelease: true,
                        DependencyBehavior.Lowest,
                        packageSourceNames,
                        CancellationToken.None);

                    Assert.NotEmpty(actions);
                    Assert.Equal(1, actions.Count);

                    ProjectAction action = actions[0];

                    Assert.Equal(packageV2.Identity, action.PackageIdentity);
                    Assert.Equal(NuGetProjectActionType.Install, action.ProjectActionType);
                    Assert.Equal(projectId, action.ProjectId);

                    Assert.Equal(2, action.ImplicitActions.Count);

                    ImplicitProjectAction implicitAction = action.ImplicitActions[0];

                    Assert.Equal(packageV1.Identity, implicitAction.PackageIdentity);
                    Assert.Equal(NuGetProjectActionType.Uninstall, implicitAction.ProjectActionType);

                    implicitAction = action.ImplicitActions[1];

                    Assert.Equal(packageV2.Identity, implicitAction.PackageIdentity);
                    Assert.Equal(NuGetProjectActionType.Install, implicitAction.ProjectActionType);
                });
            }
        }
예제 #29
0
        /// <summary>
        /// Convert MSBuild items to a DependencyGraphSpec.
        /// </summary>
        public static DependencyGraphSpec GetDependencySpec(IEnumerable <IMSBuildItem> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            // Unique names created by the MSBuild restore target are project paths, these
            // can be different on case-insensitive file systems for the same project file.
            // To workaround this unique names should be compared based on the OS.
            var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS();

            var graphSpec         = new DependencyGraphSpec();
            var itemsById         = new Dictionary <string, List <IMSBuildItem> >(uniqueNameComparer);
            var restoreSpecs      = new HashSet <string>(uniqueNameComparer);
            var validForRestore   = new HashSet <string>(uniqueNameComparer);
            var projectPathLookup = new Dictionary <string, string>(uniqueNameComparer);
            var toolItems         = new List <IMSBuildItem>();

            // Sort items and add restore specs
            foreach (var item in items)
            {
                var projectUniqueName = item.GetProperty("ProjectUniqueName");

                if (item.IsType("restorespec"))
                {
                    restoreSpecs.Add(projectUniqueName);
                }
                else if (!string.IsNullOrEmpty(projectUniqueName))
                {
                    List <IMSBuildItem> idItems;
                    if (!itemsById.TryGetValue(projectUniqueName, out idItems))
                    {
                        idItems = new List <IMSBuildItem>(1);
                        itemsById.Add(projectUniqueName, idItems);
                    }

                    idItems.Add(item);
                }
            }

            // Add projects
            var validProjectSpecs = itemsById.Values.Select(GetPackageSpec).Where(e => e != null);

            foreach (var spec in validProjectSpecs)
            {
                // Keep track of all project path casings
                var uniqueName = spec.RestoreMetadata.ProjectUniqueName;
                if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName))
                {
                    projectPathLookup.Add(uniqueName, uniqueName);
                }

                var projectPath = spec.RestoreMetadata.ProjectPath;
                if (projectPath != null && !projectPathLookup.ContainsKey(projectPath))
                {
                    projectPathLookup.Add(projectPath, projectPath);
                }

                if (spec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetToolReference)
                {
                    validForRestore.Add(spec.RestoreMetadata.ProjectUniqueName);
                }

                graphSpec.AddProject(spec);
            }

            // Fix project reference casings to match the original project on case insensitive file systems.
            NormalizePathCasings(projectPathLookup, graphSpec);

            // Remove references to projects that could not be read by restore.
            RemoveMissingProjects(graphSpec);

            // Add valid projects to restore section
            foreach (var projectUniqueName in restoreSpecs.Intersect(validForRestore))
            {
                graphSpec.AddRestore(projectUniqueName);
            }

            return(graphSpec);
        }
        public async Task RestoreBuildTargetsAndProps_VerifyRestoreChangeAsync()
        {
            // Arrange
            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var logger  = new TestLogger();
                    var sources = new List <PackageSource>
                    {
                        new PackageSource(pathContext.PackageSource)
                    };

                    var spec = GetProject("projectA", "net462", "netstandard1.6");

                    spec.RestoreMetadata.CrossTargeting = true;
                    spec.Dependencies.Add(new LibraryDependency()
                    {
                        LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package)
                    });

                    // Create fake projects, the real data is in the specs
                    var projects = CreateProjectsFromSpecs(pathContext, spec);

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();
                    dgFile.AddProject(spec);
                    dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName);
                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    var packageX = new SimpleTestPackageContext()
                    {
                        Id      = "x",
                        Version = "1.0.0"
                    };

                    var packageY = new SimpleTestPackageContext()
                    {
                        Id      = "y",
                        Version = "1.0.0"
                    };

                    packageX.AddFile("build/x.targets");
                    packageX.AddFile("build/x.props");
                    packageX.AddFile("contentFiles/any/any/_._");

                    packageY.AddFile("build/y.targets");
                    packageY.AddFile("build/y.props");
                    packageY.AddFile("contentFiles/any/any/_._");

                    await SimpleTestPackageUtility.CreatePackagesAsync(pathContext.PackageSource, packageX, packageY);

                    var project = projects[0];

                    // First restore
                    var summaries = await RunRestoreAsync(pathContext, logger, sources, dgFile, cacheContext);

                    var success = summaries.All(s => s.Success);
                    Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));

                    // Modify spec
                    spec.Dependencies.Add(new LibraryDependency()
                    {
                        LibraryRange = new LibraryRange("y", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package)
                    });

                    // Act
                    summaries = await RunRestoreAsync(pathContext, logger, sources, dgFile, cacheContext);

                    success = summaries.All(s => s.Success);
                    Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));

                    // Verify the file was rewritten
                    Assert.Contains("y.targets", File.ReadAllText(project.TargetsOutput));
                    Assert.Contains("y.props", File.ReadAllText(project.PropsOutput));
                }
        }