From cd11f71428a7f0aa70d77e419f75930981437543 Mon Sep 17 00:00:00 2001
From: Pranav K <prkrishn@hotmail.com>
Date: Thu, 13 Jul 2017 16:44:29 -0700
Subject: [PATCH] Pin CLI tool references for all projects in a solution

---
 tools/PinVersions/PinVersionUtility.cs | 54 ++++++++++++++++++--------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/tools/PinVersions/PinVersionUtility.cs b/tools/PinVersions/PinVersionUtility.cs
index 42d1e901768..d7f2fe70aa5 100644
--- a/tools/PinVersions/PinVersionUtility.cs
+++ b/tools/PinVersions/PinVersionUtility.cs
@@ -40,13 +40,18 @@ namespace PinVersions
 
         public void Execute()
         {
-            var solutionPinMetadata = GetPinVersionMetadata();
-            foreach (var item in solutionPinMetadata)
+            var solutionPinMetadata = GetProjectPinVersionMetadata();
+            foreach (var cliToolReference in solutionPinMetadata.CLIToolReferences)
+            {
+                Console.WriteLine($"Pinning CLI Tool {cliToolReference.Item1.Name}({cliToolReference.Item1.VersionRange} to {cliToolReference.Item2} for all projects in {_repositoryRoot}.");
+            }
+
+            foreach (var item in solutionPinMetadata.PinVersionLookup)
             {
                 var projectPinMetadata = item.Value;
                 var specProject = projectPinMetadata.PackageSpec;
 
-                if (!(projectPinMetadata.Packages.Any() || projectPinMetadata.CLIToolReferences.Any()))
+                if (!(projectPinMetadata.Packages.Any() || solutionPinMetadata.CLIToolReferences.Any()))
                 {
                     Console.WriteLine($"No package or tool references to pin for {specProject.FilePath}.");
                     continue;
@@ -59,7 +64,11 @@ namespace PinVersions
 
                 Directory.CreateDirectory(Path.GetDirectoryName(pinnedReferencesFile));
 
-                Console.WriteLine($"Pinning package versions for {specProject.FilePath}.");
+                if (projectPinMetadata.Packages.Any())
+                {
+                    Console.WriteLine($"Pinning package versions for {specProject.FilePath}.");
+                }
+
                 var pinnedReferences = new XElement("ItemGroup");
                 foreach (var packageReference in projectPinMetadata.Packages)
                 {
@@ -79,10 +88,10 @@ namespace PinVersions
                     pinnedReferences.Add(new XElement("PackageReference", metadata));
                 }
 
-                foreach (var toolReference in projectPinMetadata.CLIToolReferences)
+                // CLI Tool references are specified at solution level.
+                foreach (var toolReference in solutionPinMetadata.CLIToolReferences)
                 {
                     (var libraryRange, var exactVersion) = toolReference;
-                    Console.WriteLine($"Pinning CLI Tool {libraryRange.Name}({libraryRange.VersionRange} to {exactVersion}.");
                     var metadata = new List<XAttribute>
                     {
                         new XAttribute("Update", libraryRange.Name),
@@ -97,10 +106,11 @@ namespace PinVersions
             }
         }
 
-        private IDictionary<string, PinVersionMetadata> GetPinVersionMetadata()
+        private SolutionPinVersionMetadata GetProjectPinVersionMetadata()
         {
             var repositoryDirectoryInfo = new DirectoryInfo(_repositoryRoot);
-            var projects = new Dictionary<string, PinVersionMetadata>(StringComparer.OrdinalIgnoreCase);
+            var projects = new Dictionary<string, ProjectPinVersionMetadata>(StringComparer.OrdinalIgnoreCase);
+            var cliToolReferences = new List<(LibraryRange, NuGetVersion)>();
 
             foreach (var slnFile in repositoryDirectoryInfo.EnumerateFiles("*.sln"))
             {
@@ -109,7 +119,7 @@ namespace PinVersions
                 {
                     if (!projects.TryGetValue(specProject.FilePath, out var pinMetadata))
                     {
-                        pinMetadata = new PinVersionMetadata(specProject);
+                        pinMetadata = new ProjectPinVersionMetadata(specProject);
                         projects[specProject.FilePath] = pinMetadata;
                     }
 
@@ -139,7 +149,7 @@ namespace PinVersions
                         }
                         else if (projectStyle == ProjectStyle.DotnetCliTool)
                         {
-                            pinMetadata.CLIToolReferences.Add((reference.LibraryRange, exactVersion));
+                            cliToolReferences.Add((reference.LibraryRange, exactVersion));
                         }
                         else
                         {
@@ -149,7 +159,7 @@ namespace PinVersions
                 }
             }
 
-            return projects;
+            return new SolutionPinVersionMetadata(projects, cliToolReferences);
         }
 
         private NuGetVersion GetExactVersion(string name, VersionRange range)
@@ -188,20 +198,32 @@ namespace PinVersions
             return null;
         }
 
-        private struct PinVersionMetadata
+        private struct SolutionPinVersionMetadata
+        {
+            public SolutionPinVersionMetadata(
+                IDictionary<string, ProjectPinVersionMetadata> pinVersionLookup,
+                List<(LibraryRange, NuGetVersion)> cliToolReferences)
+            {
+                PinVersionLookup = pinVersionLookup;
+                CLIToolReferences = cliToolReferences;
+            }
+
+            public IDictionary<string, ProjectPinVersionMetadata> PinVersionLookup { get; }
+
+            public List<(LibraryRange, NuGetVersion)> CLIToolReferences { get; }
+        }
+
+        private struct ProjectPinVersionMetadata
         {
-            public PinVersionMetadata(PackageSpec packageSpec)
+            public ProjectPinVersionMetadata(PackageSpec packageSpec)
             {
                 PackageSpec = packageSpec;
                 Packages = new List<(NuGetFramework, LibraryRange, NuGetVersion)>();
-                CLIToolReferences = new List<(LibraryRange, NuGetVersion)>();
             }
 
             public PackageSpec PackageSpec { get; }
 
             public List<(NuGetFramework, LibraryRange, NuGetVersion)> Packages { get; }
-
-            public List<(LibraryRange, NuGetVersion)> CLIToolReferences { get; }
         }
     }
 }
-- 
GitLab