| File: Migrations\MigrationRunner.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Common\NuGet.Common.csproj (NuGet.Common) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Threading; namespace NuGet.Common.Migrations { public static class MigrationRunner { private const string MaxMigrationFilename = "1"; public static void Run() { Run(EnvironmentVariableWrapper.Instance); } internal static void Run(IEnvironmentVariableReader environmentVariableReader) { string migrationsDirectory = GetMigrationsDirectory(environmentVariableReader); Run(migrationsDirectory, environmentVariableReader); } internal static void Run(string migrationsDirectory, IEnvironmentVariableReader environmentVariableReader) { if (CommonEventSource.Instance.IsEnabled()) CommonEventSource.Instance.MigrationRunner_RunStart(); var migrationPerformed = false; var expectedMigrationFilename = Path.Combine(migrationsDirectory, MaxMigrationFilename); try { if (!File.Exists(expectedMigrationFilename)) { // Multiple processes or threads might be trying to call this concurrently (especially via NuGetSdkResolver) // so use a global mutex and then check if someone else already did the work. using (var mutex = new Mutex(false, "NuGet-Migrations")) { if (WaitForMutex(mutex)) { try { Directory.CreateDirectory(migrationsDirectory); // Only run migrations that have not already been run if (!File.Exists(expectedMigrationFilename)) { migrationPerformed = true; Migration1.Run(environmentVariableReader); // Create file for the migration run, so that if an older version of NuGet is run, it doesn't try to run migrations again. File.WriteAllText(expectedMigrationFilename, string.Empty); } } catch { } finally { mutex.ReleaseMutex(); } } } } } finally { if (CommonEventSource.Instance.IsEnabled()) CommonEventSource.Instance.MigrationRunner_RunStop(expectedMigrationFilename, migrationPerformed ? 1 : 0); } static bool WaitForMutex(Mutex mutex) { bool captured; try { captured = mutex.WaitOne(TimeSpan.FromMinutes(1), false); } catch (AbandonedMutexException) { captured = true; } return captured; } } internal static string GetMigrationsDirectory(IEnvironmentVariableReader environmentVariableReader) { if (RuntimeEnvironmentHelper.IsWindows) { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NuGet", "Migrations"); } var XdgDataHome = environmentVariableReader.GetEnvironmentVariable("XDG_DATA_HOME"); return string.IsNullOrEmpty(XdgDataHome) ? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "NuGet", "Migrations") : Path.Combine(XdgDataHome, "NuGet", "Migrations"); } } }