public static IReadOnlyList <PackageIdentity> GetOrderedProjectDependencies(
            BuildIntegratedNuGetProject buildIntegratedProject)
        {
            var results = new List <PackageIdentity>();

            var lockFilePath   = ProjectJsonPathUtilities.GetLockFilePath(buildIntegratedProject.JsonConfigPath);
            var lockFileFormat = new LockFileFormat();

            // Read the lock file to find the full closure of dependencies
            if (File.Exists(lockFilePath))
            {
                var lockFile = lockFileFormat.Read(lockFilePath);

                var dependencies = new HashSet <PackageDependencyInfo>(PackageIdentity.Comparer);

                foreach (var target in lockFile.Targets)
                {
                    foreach (var targetLibrary in target.Libraries)
                    {
                        var identity   = new PackageIdentity(targetLibrary.Name, targetLibrary.Version);
                        var dependency = new PackageDependencyInfo(identity, targetLibrary.Dependencies);
                        dependencies.Add(dependency);
                    }
                }

                // Sort dependencies
                var sortedDependencies = SortPackagesByDependencyOrder(dependencies);
                results.AddRange(sortedDependencies);
            }

            return(results);
        }
Exemple #2
0
        private IVsPathContext GetPathContextForProjectJson(
            IVsProjectAdapter vsProjectAdapter)
        {
            // generate project.lock.json file path from project file
            var projectFilePath = vsProjectAdapter.FullProjectPath;

            if (!string.IsNullOrEmpty(projectFilePath))
            {
                var msbuildProjectFile         = new FileInfo(projectFilePath);
                var projectNameFromMSBuildPath = Path.GetFileNameWithoutExtension(msbuildProjectFile.Name);

                string projectJsonPath = null;
                if (string.IsNullOrEmpty(projectNameFromMSBuildPath))
                {
                    projectJsonPath = Path.Combine(msbuildProjectFile.DirectoryName,
                                                   ProjectJsonPathUtilities.ProjectConfigFileName);
                }
                else
                {
                    projectJsonPath = ProjectJsonPathUtilities.GetProjectConfigPath(
                        msbuildProjectFile.DirectoryName,
                        projectNameFromMSBuildPath);
                }

                if (File.Exists(projectJsonPath))
                {
                    var lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(projectJsonPath);
                    return(GetPathContextFromProjectLockFile(lockFilePath));
                }
            }

            return(null);
        }
Exemple #3
0
        public void ApplyStandardProperties(RestoreRequest request)
        {
            request.PackageSaveMode = PackageSaveMode;

            if (request.ProjectStyle == ProjectStyle.PackageReference ||
                request.ProjectStyle == ProjectStyle.DotnetToolReference ||
                request.ProjectStyle == ProjectStyle.Standalone)
            {
                request.LockFilePath = Path.Combine(request.RestoreOutputPath, LockFileFormat.AssetsFileName);
            }
            else if (request.ProjectStyle != ProjectStyle.DotnetCliTool)
            {
                request.LockFilePath = ProjectJsonPathUtilities.GetLockFilePath(request.Project.FilePath);
            }

            if (request.Project.RestoreMetadata?.CacheFilePath == null)
            {
                request.Project.RestoreMetadata.CacheFilePath = NoOpRestoreUtilities.GetCacheFilePath(request);
            }

            request.MaxDegreeOfConcurrency =
                DisableParallel ? 1 : RestoreRequest.DefaultDegreeOfConcurrency;

            request.RequestedRuntimes.UnionWith(Runtimes);
            request.FallbackRuntimes.UnionWith(FallbackRuntimes);

            if (IsLowercaseGlobalPackagesFolder.HasValue)
            {
                request.IsLowercasePackagesDirectory = IsLowercaseGlobalPackagesFolder.Value;
            }

            if (LockFileVersion.HasValue && LockFileVersion.Value > 0)
            {
                request.LockFileVersion = LockFileVersion.Value;
            }

            // Run runtime asset checks for project.json, and for other types if enabled.
            if (ValidateRuntimeAssets == null)
            {
                if (request.ProjectStyle == ProjectStyle.ProjectJson ||
                    request.Project.RestoreMetadata == null)
                {
                    request.ValidateRuntimeAssets = request.ProjectStyle == ProjectStyle.ProjectJson;
                }
                else
                {
                    request.ValidateRuntimeAssets = request.Project.RestoreMetadata.ValidateRuntimeAssets;
                }
            }
            else
            {
                request.ValidateRuntimeAssets = ValidateRuntimeAssets.Value;
            }

            request.AllowNoOp             = !request.CacheContext.NoCache && AllowNoOp;
            request.HideWarningsAndErrors = HideWarningsAndErrors;
            request.ParentId = ParentId;
            request.IsRestoreOriginalAction = IsRestoreOriginalAction;
            request.ReevaluateRestoreGraph  = ReevaluateRestoreGraph;
        }
        public void ProjectJsonPathUtilities_GetLockFilePath(string configPath, string lockFilePath)
        {
            // Arrange & Act
            var result = ProjectJsonPathUtilities.GetLockFilePath(ConvertToUnix(configPath));

            // Assert
            Assert.Equal(ConvertToUnix(lockFilePath), result);
        }
Exemple #5
0
        /// <summary>
        /// Restore without writing the lock file
        /// </summary>
        internal static async Task <RestoreResult> RestoreAsync(
            BuildIntegratedNuGetProject project,
            PackageSpec packageSpec,
            ExternalProjectReferenceContext context,
            RestoreCommandProviders providers,
            CancellationToken token)
        {
            // Restoring packages
            var logger = context.Logger;

            logger.LogMinimal(string.Format(CultureInfo.CurrentCulture,
                                            Strings.BuildIntegratedPackageRestoreStarted,
                                            project.ProjectName));

            using (var request = new RestoreRequest(packageSpec, providers, logger, disposeProviders: false))
            {
                request.MaxDegreeOfConcurrency = PackageManagementConstants.DefaultMaxDegreeOfParallelism;
                request.LockFileVersion        = await GetLockFileVersion(project, context);

                // Add the existing lock file if it exists
                var lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(project.JsonConfigPath);
                request.LockFilePath     = lockFilePath;
                request.ExistingLockFile = LockFileUtilities.GetLockFile(lockFilePath, logger);

                // Find the full closure of project.json files and referenced projects
                var projectReferences = await project.GetProjectReferenceClosureAsync(context);

                request.ExternalProjects = projectReferences.ToList();

                token.ThrowIfCancellationRequested();

                var command = new RestoreCommand(request);

                // Execute the restore
                var result = await command.ExecuteAsync(token);

                // Report a final message with the Success result
                if (result.Success)
                {
                    logger.LogMinimal(string.Format(CultureInfo.CurrentCulture,
                                                    Strings.BuildIntegratedPackageRestoreSucceeded,
                                                    project.ProjectName));
                }
                else
                {
                    logger.LogMinimal(string.Format(CultureInfo.CurrentCulture,
                                                    Strings.BuildIntegratedPackageRestoreFailed,
                                                    project.ProjectName));
                }

                return(result);
            }
        }
Exemple #6
0
        public override bool Execute()
        {
            var packagesChecked = new HashSet <PackageIdentity>();
            var packageResolver = new VersionFolderPathResolver(PackagesFolder);
            var needsRestore    = new LinkedList <ITaskItem>();
            var lockFileFormat  = new LockFileFormat();

            ProjectJsons.AsParallel().ForAll(project =>
            {
                string projectJsonPath     = project.GetMetadata("FullPath");
                string projectLockJsonPath = ProjectJsonPathUtilities.GetLockFilePath(projectJsonPath);

                if (!File.Exists(projectLockJsonPath))
                {
                    Log.LogMessage(MessageImportance.Low, $"{projectJsonPath} requires restore because {projectLockJsonPath} is missing.");
                    AddLock(needsRestore, project);
                    return;
                }

                if (File.GetLastWriteTime(projectJsonPath) > File.GetLastWriteTime(projectLockJsonPath))
                {
                    Log.LogMessage(MessageImportance.Low, $"{projectJsonPath} requires restore because {projectLockJsonPath} is older.");
                    AddLock(needsRestore, project);
                    return;
                }

                var packages = ReadPackages(projectLockJsonPath);

                foreach (var package in packages)
                {
                    // Each id/version only needs to be checked once
                    if (AddLock(packagesChecked, package))
                    {
                        // Verify the SHA exists for each package, don't validate the content since we assume our packages are immutable
                        var hashPath = packageResolver.GetHashPath(package.Id, package.Version);

                        if (!File.Exists(hashPath))
                        {
                            Log.LogMessage(MessageImportance.Low, $"{projectJsonPath} requires restore because {package} is missing.");
                            AddLock(needsRestore, project);
                            break;
                        }
                    }
                }
            });

            ProjectJsonsRequiringRestore = needsRestore.ToArray();
            RestoreRequired = ProjectJsonsRequiringRestore.Length > 0;

            return(!Log.HasLoggedErrors);
        }
Exemple #7
0
        public void ApplyStandardProperties(RestoreRequest request)
        {
            request.PackageSaveMode = PackageSaveMode;

            var lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(request.Project.FilePath);

            request.LockFilePath = lockFilePath;

            request.MaxDegreeOfConcurrency =
                DisableParallel ? 1 : RestoreRequest.DefaultDegreeOfConcurrency;

            request.RequestedRuntimes.UnionWith(Runtimes);
            request.FallbackRuntimes.UnionWith(FallbackRuntimes);

            if (LockFileVersion.HasValue && LockFileVersion.Value > 0)
            {
                request.LockFileVersion = LockFileVersion.Value;
            }
        }
Exemple #8
0
 public override Task <string> GetAssetsFilePathAsync()
 {
     return(Task.FromResult(ProjectJsonPathUtilities.GetLockFilePath(JsonConfigPath)));
 }
Exemple #9
0
        /// <summary>
        /// Validate that all project.lock.json files are validate for the project.json files,
        /// and that no packages are missing.
        /// If a full restore is required this will return false.
        /// </summary>
        /// <remarks>Floating versions and project.json files with supports require a full restore.</remarks>
        public static async Task <bool> IsRestoreRequired(
            IReadOnlyList <BuildIntegratedNuGetProject> projects,
            VersionFolderPathResolver pathResolver,
            ExternalProjectReferenceContext referenceContext)
        {
            var hashesChecked = new HashSet <string>();

            // Validate project.lock.json files
            foreach (var project in projects)
            {
                var lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(project.JsonConfigPath);

                if (!File.Exists(lockFilePath))
                {
                    // If the lock file does not exist a restore is needed
                    return(true);
                }

                var lockFileFormat = new LockFileFormat();
                var lockFile       = lockFileFormat.Read(lockFilePath, referenceContext.Logger);

                var lockFileVersion = await GetLockFileVersion(project, referenceContext);

                var packageSpec = referenceContext.GetOrCreateSpec(project.ProjectName, project.JsonConfigPath);

                if (!lockFile.IsValidForPackageSpec(packageSpec, lockFileVersion))
                {
                    // The project.json file has been changed and the lock file needs to be updated.
                    return(true);
                }

                // Verify all libraries are on disk
                foreach (var library in lockFile.Libraries)
                {
                    // Verify the SHA for each package
                    var hashPath = pathResolver.GetHashPath(library.Name, library.Version);

                    // Libraries shared between projects can be skipped
                    if (hashesChecked.Add(hashPath))
                    {
                        if (File.Exists(hashPath))
                        {
                            var sha512 = File.ReadAllText(hashPath);

                            if (library.Sha512 != sha512)
                            {
                                // A package has changed
                                return(true);
                            }
                        }
                        else
                        {
                            // A package is missing
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Exemple #10
0
        private static bool IsRestoreRequired(
            PackageSpec packageSpec,
            IEnumerable <VersionFolderPathResolver> pathResolvers,
            ISet <PackageIdentity> packagesChecked,
            DependencyGraphCacheContext context)
        {
            var lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(packageSpec.RestoreMetadata.ProjectJsonPath);

            if (!File.Exists(lockFilePath))
            {
                // If the lock file does not exist a restore is needed
                return(true);
            }

            var      lockFileFormat = new LockFileFormat();
            LockFile lockFile;

            try
            {
                lockFile = lockFileFormat.Read(lockFilePath, context.Logger);
            }
            catch
            {
                // If the lock file is invalid, then restore.
                return(true);
            }

            // Verify all libraries are on disk
            var packages = lockFile.Libraries.Where(library => library.Type == LibraryType.Package);

            foreach (var library in packages)
            {
                var identity = new PackageIdentity(library.Name, library.Version);

                // Each id/version only needs to be checked once
                if (packagesChecked.Add(identity))
                {
                    var found = false;

                    //  Check each package folder. These need to match the order used for restore.
                    foreach (var resolver in pathResolvers)
                    {
                        // Verify the SHA for each package
                        var hashPath = resolver.GetHashPath(library.Name, library.Version);

                        if (File.Exists(hashPath))
                        {
                            found = true;
                            var sha512 = File.ReadAllText(hashPath);

                            if (library.Sha512 != sha512)
                            {
                                // A package has changed
                                return(true);
                            }

                            // Skip checking the rest of the package folders
                            break;
                        }
                    }

                    if (!found)
                    {
                        // A package is missing
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #11
0
        /// <summary>
        /// Validate that all project.lock.json files are validate for the project.json files,
        /// and that no packages are missing.
        /// If a full restore is required this will return false.
        /// </summary>
        /// <remarks>Floating versions and project.json files with supports require a full restore.</remarks>
        public static async Task <bool> IsRestoreRequired(
            IReadOnlyList <BuildIntegratedNuGetProject> projects,
            IReadOnlyList <string> packageFolderPaths,
            ExternalProjectReferenceContext referenceContext)
        {
            var packagesChecked = new HashSet <PackageIdentity>();
            var pathResolvers   = packageFolderPaths.Select(path => new VersionFolderPathResolver(path));

            // Validate project.lock.json files
            foreach (var project in projects)
            {
                var lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(project.JsonConfigPath);

                if (!File.Exists(lockFilePath))
                {
                    // If the lock file does not exist a restore is needed
                    return(true);
                }

                var lockFileFormat = new LockFileFormat();
                var lockFile       = lockFileFormat.Read(lockFilePath, referenceContext.Logger);

                var lockFileVersion = await GetLockFileVersion(project, referenceContext);

                var packageSpec = referenceContext.GetOrCreateSpec(project.ProjectName, project.JsonConfigPath);

                if (!lockFile.IsValidForPackageSpec(packageSpec, lockFileVersion))
                {
                    // The project.json file has been changed and the lock file needs to be updated.
                    return(true);
                }

                // Verify all libraries are on disk
                foreach (var library in lockFile.Libraries)
                {
                    var identity = new PackageIdentity(library.Name, library.Version);

                    // Each id/version only needs to be checked once
                    if (packagesChecked.Add(identity))
                    {
                        var found = false;

                        //  Check each package folder. These need to match the order used for restore.
                        foreach (var resolver in pathResolvers)
                        {
                            // Verify the SHA for each package
                            var hashPath = resolver.GetHashPath(library.Name, library.Version);

                            if (File.Exists(hashPath))
                            {
                                found = true;
                                var sha512 = File.ReadAllText(hashPath);

                                if (library.Sha512 != sha512)
                                {
                                    // A package has changed
                                    return(true);
                                }

                                // Skip checking the rest of the package folders
                                break;
                            }
                        }

                        if (!found)
                        {
                            // A package is missing
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public override bool TryGetPackages(string packageConfigPath, PackageRestoreData packageRestoreData, out IEnumerable <PackageIdentityWithPath> packages)
        {
            packages = null;

            string projectJsonPath;

            if (ProjectJsonPathUtilities.IsProjectConfig(packageConfigPath))
            {
                projectJsonPath = packageConfigPath;
            }
            else
            {
                if (!String.Equals("ProjectJson", packageRestoreData?.RestoreProjectStyle, StringComparison.OrdinalIgnoreCase) || String.IsNullOrWhiteSpace(packageRestoreData?.ProjectJsonPath))
                {
                    return(false);
                }

                projectJsonPath = packageRestoreData.ProjectJsonPath;
            }

            string lockFilePath = ProjectJsonPathUtilities.GetLockFilePath(projectJsonPath);

            if (!File.Exists(lockFilePath))
            {
                throw new FileNotFoundException($"The lock file '{lockFilePath}' does not exist.  Ensure that the restore succeeded and that the lock file was generated.");
            }

            LockFile lockFile = LockFileUtilities.GetLockFile(lockFilePath, NullLogger.Instance);

            string globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(NuGetSettings);

            if (String.IsNullOrWhiteSpace(globalPackagesFolder))
            {
                throw new NuGetConfigurationException(@"Unable to determine the NuGet repository path.  This usually defaults to ""%UserProfile%\.nuget\packages"", ""%NUGET_PACKAGES%"", or the ""globalPackagesFolder"" in your NuGet.config.");
            }

            globalPackagesFolder = Path.GetFullPath(globalPackagesFolder);

            if (!Directory.Exists(globalPackagesFolder))
            {
                throw new DirectoryNotFoundException($"The NuGet repository '{globalPackagesFolder}' does not exist.  Ensure that NuGet is restore packages to the location specified in your NuGet.config.");
            }

            Log.LogMessage(MessageImportance.Low, $"Using repository path: '{globalPackagesFolder}'");

            VersionFolderPathResolver versionFolderPathResolver = new VersionFolderPathResolver(globalPackagesFolder);

            packages = lockFile.Libraries.Select(i =>
            {
                string installPath = versionFolderPathResolver.GetInstallPath(i.Name, i.Version);

                if (!String.IsNullOrWhiteSpace(installPath))
                {
                    installPath = Path.GetFullPath(installPath);
                }
                else
                {
                    Log.LogWarning($"The package '{i.Name}' was not found in the repository.");
                }

                return(new PackageIdentityWithPath(i.Name, i.Version, installPath));
            }).Where(i => !String.IsNullOrWhiteSpace(i.FullPath));

            return(true);
        }