Enabling SDK mutilevel lookup to pick the highest semantical version out of all viabl...
authorJohn Beisner <jbeisner@microsoft.com>
Thu, 18 May 2017 21:21:37 +0000 (14:21 -0700)
committerJohn Beisner <jbeisner@microsoft.com>
Fri, 19 May 2017 20:30:06 +0000 (13:30 -0700)
Commit migrated from https://github.com/dotnet/core-setup/commit/2e68a683c1077a826c969cd52344f474e8e5856c

src/installer/corehost/cli/fxr/fx_muxer.cpp
src/installer/test/HostActivationTests/GivenThatICareAboutMultilevelSDKLookup.cs

index 78980e1..441e693 100644 (file)
@@ -563,7 +563,7 @@ pal::string_t fx_muxer_t::resolve_cli_version(const pal::string_t& global_json)
     return retval;
 }
 
-pal::string_t resolve_sdk_version(pal::string_t sdk_path)
+pal::string_t resolve_sdk_version(pal::string_t sdk_path, bool parse_only_production)
 {
     trace::verbose(_X("--- Resolving SDK version from SDK dir [%s]"), sdk_path.c_str());
 
@@ -577,7 +577,7 @@ pal::string_t resolve_sdk_version(pal::string_t sdk_path)
         trace::verbose(_X("Considering version... [%s]"), version.c_str());
 
         fx_ver_t ver(-1, -1, -1);
-        if (fx_ver_t::parse(version, &ver, false))  // false -- implies both production and prerelease.
+        if (fx_ver_t::parse(version, &ver, parse_only_production))
         {
             max_ver = std::max(ver, max_ver);
         }
@@ -589,10 +589,10 @@ pal::string_t resolve_sdk_version(pal::string_t sdk_path)
     trace::verbose(_X("Checking if resolved SDK dir [%s] exists"), sdk_path.c_str());
     if (pal::directory_exists(sdk_path))
     {
+        trace::verbose(_X("Resolved SDK dir is [%s]"), sdk_path.c_str());
         retval = max_ver_str;
     }
 
-    trace::verbose(_X("Resolved SDK dir is [%s]"), sdk_path.c_str());
     return retval;
 }
 
@@ -609,6 +609,24 @@ bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::stri
     return resolve_sdk_dotnet_path(own_dir, cwd, cli_sdk);
 }
 
+bool higher_sdk_version(const pal::string_t& new_version, pal::string_t* version, bool parse_only_production)
+{
+    bool retval = false;
+    fx_ver_t ver(-1, -1, -1);
+    fx_ver_t new_ver(-1, -1, -1);
+
+    if (fx_ver_t::parse(new_version, &new_ver, parse_only_production))
+    {
+       if (!fx_ver_t::parse(*version, &ver, parse_only_production) || (new_ver > ver))
+       {
+           version->assign(new_version);
+           retval = true;
+       }
+    }
+
+    return retval;
+}
+
 bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, const pal::string_t& cwd, pal::string_t* cli_sdk)
 {
     pal::string_t global;
@@ -661,47 +679,61 @@ bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, const pal
 
     bool cli_version_specified = false;
     pal::string_t cli_version;
-    pal::string_t probing_cli_version;
-    pal::string_t probing_sdk_path;
+    pal::string_t sdk_path;
+    pal::string_t global_cli_version;
+
+    if (!global.empty())
+    {
+        global_cli_version = resolve_cli_version(global);
+        if (!global_cli_version.empty())
+        {
+            cli_version_specified = true;
+        }
+    }
 
     for (pal::string_t dir : hive_dir)
     {
         trace::verbose(_X("Searching SDK directory in [%s]"), dir.c_str());
-        pal::string_t sdk_path = dir;
-        append_path(&sdk_path, _X("sdk"));
-        if (!global.empty())
+        pal::string_t current_sdk_path = dir;
+        append_path(&current_sdk_path, _X("sdk"));
+
+        if (cli_version_specified)
         {
-            probing_cli_version = resolve_cli_version(global);
-            if (!probing_cli_version.empty())
-            {
-                cli_version_specified = true;
-                probing_sdk_path = sdk_path;
-                append_path(&probing_sdk_path, probing_cli_version.c_str());
+            pal::string_t probing_sdk_path = current_sdk_path;
+            append_path(&probing_sdk_path, global_cli_version.c_str());
 
-                if (pal::directory_exists(probing_sdk_path))
-                {
-                    trace::verbose(_X("CLI directory [%s] from global.json exists"), probing_sdk_path.c_str());
-                    cli_version = probing_cli_version;
-                }
-                else
-                {
-                    trace::verbose(_X("CLI directory [%s] from global.json doesn't exist"), probing_sdk_path.c_str());
-                }
+            if (pal::directory_exists(probing_sdk_path))
+            {
+                trace::verbose(_X("CLI directory [%s] from global.json exists"), probing_sdk_path.c_str());
+                cli_version = global_cli_version;
+                sdk_path = current_sdk_path;
+                //  Use the first matching version
+                break;
+            }
+            else
+            {
+                trace::verbose(_X("CLI directory [%s] from global.json doesn't exist"), probing_sdk_path.c_str());
             }
         }
-        if (cli_version.empty() && !cli_version_specified)
-        {
-            cli_version = resolve_sdk_version(sdk_path);
-        }
-        if (!cli_version.empty())
+        else
         {
-            append_path(&sdk_path, cli_version.c_str());
-            cli_sdk->assign(sdk_path);
-            trace::verbose(_X("Found CLI SDK in: %s"), cli_sdk->c_str());
-            return true;
+            bool parse_only_production = false;  // false -- implies both production and prerelease.
+            pal::string_t new_cli_version = resolve_sdk_version(current_sdk_path, parse_only_production);
+            if (higher_sdk_version(new_cli_version, &cli_version, parse_only_production))
+            {
+                sdk_path = current_sdk_path;
+            }
         }
     }
     
+    if (!cli_version.empty())
+    {
+        append_path(&sdk_path, cli_version.c_str());
+        cli_sdk->assign(sdk_path);
+        trace::verbose(_X("Found CLI SDK in: %s"), cli_sdk->c_str());
+        return true;
+    }
+
     if (cli_version_specified)
     {
         trace::error(_X("The specified SDK version [%s] from global.json [%s] not found; install specified SDK version"), cli_version.c_str(), global.c_str());
index 306883b..8eb200f 100644 (file)
@@ -253,14 +253,15 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
 
             var dotnet = fixture.BuiltDotnet;
 
-            // Add a dummy version in the exe dir
+            // Add dummy versions in the exe dir
             AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.0");
+            AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.1-dummy");
 
             // Specified CLI version: none
             // CWD: empty
             // User: empty
-            // Exe: 9999.0.0
-            // Expected: 9999.0.0 from exe dir
+            // Exe: 9999.0.0, 9999.0.1-dummy
+            // Expected: 9999.0.1-dummy from exe dir
             dotnet.Exec("help")
                 .WorkingDirectory(_currentWorkingDir)
                 .WithUserProfile(_userDir)
@@ -271,7 +272,7 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
                 .Should()
                 .Pass()
                 .And
-                .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0", _dotnetSdkDllMessageTerminator));
+                .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.1-dummy", _dotnetSdkDllMessageTerminator));
 
             // Add a dummy version in the exe dir
             AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.1");
@@ -279,7 +280,7 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
             // Specified CLI version: none
             // CWD: empty
             // User: empty
-            // Exe: 9999.0.0, 9999.0.1
+            // Exe: 9999.0.0, 9999.0.1-dummy, 9999.0.1
             // Expected: 9999.0.1 from exe dir
             dotnet.Exec("help")
                 .WorkingDirectory(_currentWorkingDir)
@@ -293,14 +294,15 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
                 .And
                 .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.1", _dotnetSdkDllMessageTerminator));
 
-            // Add a dummy version in the exe dir
-            AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.0-dummy");
+            // Add dummy versions
+            AddAvailableSdkVersions(_userSdkBaseDir, "9999.0.1");
+            AddAvailableSdkVersions(_cwdSdkBaseDir, "10000.0.0");
 
             // Specified CLI version: none
-            // CWD: empty
-            // User: empty
-            // Exe: 9999.0.0, 9999.0.1, 9999.0.0-dummy
-            // Expected: 9999.0.1 from exe dir
+            // CWD: 10000.0.0                 --> should not be picked
+            // User: 9999.0.1
+            // Exe: 9999.0.0, 9999.0.1-dummy, 9999.0.1
+            // Expected: 9999.0.1 from user dir
             dotnet.Exec("help")
                 .WorkingDirectory(_currentWorkingDir)
                 .WithUserProfile(_userDir)
@@ -311,15 +313,15 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
                 .Should()
                 .Pass()
                 .And
-                .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.1", _dotnetSdkDllMessageTerminator));
+                .HaveStdErrContaining(Path.Combine(_userSelectedMessage, "9999.0.1", _dotnetSdkDllMessageTerminator));
 
             // Add a dummy version in the exe dir
             AddAvailableSdkVersions(_exeSdkBaseDir, "10000.0.0-dummy");
 
             // Specified CLI version: none
-            // CWD: empty
-            // User: empty
-            // Exe: 9999.0.0, 9999.0.1, 9999.0.0-dummy, 10000.0.0-dummy
+            // CWD: 10000.0.0                 --> should not be picked
+            // User: 9999.0.1
+            // Exe: 9999.0.0, 9999.0.1-dummy, 9999.0.1, 10000.0.0-dummy
             // Expected: 10000.0.0-dummy from exe dir
             dotnet.Exec("help")
                 .WorkingDirectory(_currentWorkingDir)
@@ -333,14 +335,14 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
                 .And
                 .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "10000.0.0-dummy", _dotnetSdkDllMessageTerminator));
 
-            // Add a dummy version in the exe dir
-            AddAvailableSdkVersions(_exeSdkBaseDir, "10000.0.0");
+            // Add a dummy version in the user dir
+            AddAvailableSdkVersions(_userSdkBaseDir, "10000.0.0");
 
             // Specified CLI version: none
-            // CWD: empty
-            // User: empty
-            // Exe: 9999.0.0, 9999.0.1, 9999.0.0-dummy, 10000.0.0-dummy, 10000.0.0
-            // Expected: 10000.0.0 from exe dir
+            // CWD: 10000.0.0                 --> should not be picked
+            // User: 9999.0.1, 10000.0.0
+            // Exe: 9999.0.0, 9999.0.1-dummy, 9999.0.1, 10000.0.0-dummy
+            // Expected: 10000.0.0 from user dir
             dotnet.Exec("help")
                 .WorkingDirectory(_currentWorkingDir)
                 .WithUserProfile(_userDir)
@@ -351,8 +353,10 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSDKLookup
                 .Should()
                 .Pass()
                 .And
-                .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "10000.0.0", _dotnetSdkDllMessageTerminator));
+                .HaveStdErrContaining(Path.Combine(_userSelectedMessage, "10000.0.0", _dotnetSdkDllMessageTerminator));
 
+            // Remove dummy folders from user dir
+            DeleteAvailableSdkVersions(_userSdkBaseDir, "9999.0.1", "10000.0.0");
         }
 
         // This method adds a list of new sdk version folders in the specified