diff --git a/NuGet.config b/NuGet.config index 628775903719..d20b1ae7404b 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,16 +4,26 @@ + + + + + + + + + + @@ -30,13 +40,25 @@ + + + + + + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7a6620193b94..78bd8c766786 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,78 +1,78 @@ - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-templating - 4ac7f473472dd810f75a183a760c16990c78fe34 + 32a619c8ec7782b8a9cd2fe6476d25197d2b4c32 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 0ec02c8c96e2eda06dc5b5edfdbdba0f36415082 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 163a63591cf9e9b682063cf3995948c2b885a042 + 5a400c212afdf8e675c9a1d38442e6d2f19f7b74 - - https://github.com/dotnet/msbuild - 80f618ad45d38475773fd1a6eaa059f118a0ad5a + + https://dev.azure.com/devdiv/DevDiv/_git/DotNet-msbuild-Trusted + 561848881bab01749e6d8b03be2869a18ca944f7 - - https://github.com/dotnet/msbuild - 80f618ad45d38475773fd1a6eaa059f118a0ad5a + + https://dev.azure.com/devdiv/DevDiv/_git/DotNet-msbuild-Trusted + 561848881bab01749e6d8b03be2869a18ca944f7 https://github.com/dotnet/fsharp @@ -113,21 +113,21 @@ https://github.com/dotnet/roslyn 954930214e5a116e3aa1f81cab887b294ae95739 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - - https://github.com/nuget/nuget.client - 222ff7a5329be15520034b76fa1a84098d2ae9fd + + https://dev.azure.com/devdiv/DevDiv/_git/NuGet-NuGet.Client-Trusted + 01bc4df1ef99c9c213f892ec8b25e46b23c7cfb1 - - https://github.com/nuget/nuget.client - 222ff7a5329be15520034b76fa1a84098d2ae9fd + + https://dev.azure.com/devdiv/DevDiv/_git/NuGet-NuGet.Client-Trusted + 01bc4df1ef99c9c213f892ec8b25e46b23c7cfb1 https://github.com/microsoft/vstest @@ -166,66 +166,66 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 70ae3df4a6f3c92fb6b315afc405edd10ff38579 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - f40e7ceff0e19c1383a2613030a5b78da8bcfed3 + 74607da18cfa95417e1bddf02c80fb97e48c7f46 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - f40e7ceff0e19c1383a2613030a5b78da8bcfed3 + 74607da18cfa95417e1bddf02c80fb97e48c7f46 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - f40e7ceff0e19c1383a2613030a5b78da8bcfed3 + 74607da18cfa95417e1bddf02c80fb97e48c7f46 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - f40e7ceff0e19c1383a2613030a5b78da8bcfed3 + 74607da18cfa95417e1bddf02c80fb97e48c7f46 - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - a97bb2af3c7d400dfe8aca3fa3d47ba83d925d6c + 3bbc77257e3d51a2e19195523eafd262da1f5459 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 https://github.com/dotnet/razor-compiler @@ -242,21 +242,21 @@ 503deb302b09bbd0ee3cb64e46117fa2d31af442 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3fe12b935c03138f76364dc877a7e069e254b5b2 + 32e8c8cae5b1a4dd752d0a42a6f8a2813f75f173 https://github.com/aspnet/xdt diff --git a/eng/Versions.props b/eng/Versions.props index 7d8ad60094dc..c7e5b61fca21 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,25 +42,25 @@ - 6.0.9 - 6.0.9-servicing.22419.5 - 6.0.9 + 6.0.10 + 6.0.10-servicing.22476.5 + 6.0.10 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 6.0.0 - 6.0.9 - 6.0.9-servicing.22419.5 + 6.0.10 + 6.0.10-servicing.22476.5 6.0.0-preview.7.21363.9 6.0.0 - 6.3.0-rc.128 + 6.3.1-rc.1 $(NuGetBuildTasksPackageVersion) 6.0.0 $(NuGetBuildTasksPackageVersion) $(NuGetBuildTasksPackageVersion) $(NuGetBuildTasksPackageVersion) - 6.3.0-rc.128 + 6.3.1-rc.1 $(NuGetBuildTasksPackageVersion) $(NuGetBuildTasksPackageVersion) $(NuGetBuildTasksPackageVersion) @@ -97,7 +97,7 @@ - 17.3.1 + 17.3.2 - 6.0.401-rtm.22420.12 - 6.0.401 - 6.0.401 - 6.0.401 - 6.0.401 + 6.0.402-rtm.22476.21 + 6.0.402 + 6.0.402 + 6.0.402 + 6.0.402 @@ -137,23 +137,23 @@ - 6.0.9-servicing.22419.26 - 6.0.9 - 6.0.9-servicing.22419.26 - 6.0.9-servicing.22419.26 - 6.0.9-servicing.22419.26 - 6.0.9 + 6.0.10-servicing.22476.17 + 6.0.10 + 6.0.10-servicing.22476.17 + 6.0.10-servicing.22476.17 + 6.0.10-servicing.22476.17 + 6.0.10 6.0.3-1.22213.1 6.0.3-1.22213.1 6.0.3-1.22213.1 - 6.0.9-servicing.22420.4 + 6.0.10-servicing.22476.4 - 6.0.9-servicing.22420.3 + 6.0.10-servicing.22476.6 diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 1fbb5db9b2f6..097514822dfb 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -66,7 +66,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var watchList = Path.GetTempFileName(); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj index 636f43d119b4..065f750f7200 100644 --- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj +++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj @@ -23,6 +23,7 @@ + diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs index 312d6fecd7d4..b063b9fc4a08 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs @@ -7,7 +7,7 @@ namespace Microsoft.Extensions.EnvironmentAbstractions { - internal class DirectoryWrapper: IDirectory + internal class DirectoryWrapper : IDirectory { public bool Exists(string path) { @@ -19,6 +19,11 @@ public ITemporaryDirectory CreateTemporaryDirectory() return new TemporaryDirectory(); } + public string CreateTemporarySubdirectory() + { + return CreateTemporaryDirectory().DirectoryPath; + } + public IEnumerable EnumerateDirectories(string path) { return Directory.EnumerateDirectories(path); diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs index 06ed28ab76d7..cf69976a0844 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs @@ -30,7 +30,7 @@ public string ToQuotedString() public override string ToString() { - return ToQuotedString(); + return Value; } public DirectoryPath GetDirectoryPath() diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs index 983bba34afc3..0a2e4e31e09f 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs @@ -24,5 +24,9 @@ internal interface IDirectory void Delete(string path, bool recursive); void Move(string source, string destination); + + + /// Returns a new directory created under the temp folder. Can be on the mock under test or the real temp file folder. + string CreateTemporarySubdirectory(); } } diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj index d82e1b61d0ec..1ac773f2f90e 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj @@ -12,4 +12,7 @@ true + + + diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs index d43683e156f5..9ce8241c8967 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs @@ -1,8 +1,9 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Extensions.EnvironmentAbstractions; using System.IO; +using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.DotNet; namespace Microsoft.DotNet.InternalAbstractions { @@ -12,8 +13,7 @@ internal class TemporaryDirectory : ITemporaryDirectory public TemporaryDirectory() { - DirectoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(DirectoryPath); + DirectoryPath = Path.Combine(PathUtilities.CreateTempSubdirectory()); } public void Dispose() diff --git a/src/Cli/dotnet/NugetPackageDownloader/FirstPartyNuGetPackageSigningVerifier.cs b/src/Cli/dotnet/NugetPackageDownloader/FirstPartyNuGetPackageSigningVerifier.cs index 283fbc886e1a..b98ba43e157f 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/FirstPartyNuGetPackageSigningVerifier.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/FirstPartyNuGetPackageSigningVerifier.cs @@ -27,7 +27,7 @@ internal class FirstPartyNuGetPackageSigningVerifier : IFirstPartyNuGetPackageSi }; private readonly HashSet _upperFirstPartyCertificateThumbprints = - new(StringComparer.OrdinalIgnoreCase) {"51044706BD237B91B89B781337E6D62656C69F0FCFFBE8E43741367948127862"}; + new(StringComparer.OrdinalIgnoreCase) { "51044706BD237B91B89B781337E6D62656C69F0FCFFBE8E43741367948127862" }; private const string FirstPartyCertificateSubject = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"; @@ -37,7 +37,7 @@ internal class FirstPartyNuGetPackageSigningVerifier : IFirstPartyNuGetPackageSi public FirstPartyNuGetPackageSigningVerifier(DirectoryPath? tempDirectory = null, ILogger logger = null) { - _tempDirectory = tempDirectory ?? new DirectoryPath(Path.GetTempPath()); + _tempDirectory = tempDirectory ?? new DirectoryPath(PathUtilities.CreateTempSubdirectory()); _logger = logger ?? new NullLogger(); } @@ -84,7 +84,7 @@ internal bool IsFirstParty(FilePath nupkgToVerify) private static bool NuGetVerify(FilePath nupkgToVerify, out string commandOutput) { - var args = new[] {"verify", "--all", nupkgToVerify.Value}; + var args = new[] { "verify", "--all", nupkgToVerify.Value }; var command = new DotNetCommandFactory(alwaysRunOutOfProc: true) .Create("nuget", args); diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 4dee9748d079..68390f1f2ce2 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -85,7 +85,8 @@ public void CreateShim(FilePath targetExecutablePath, ToolCommandName commandNam ex); } }, - rollback: () => { + rollback: () => + { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { File.Delete(file.Value); @@ -97,12 +98,13 @@ public void RemoveShim(ToolCommandName commandName) { var files = new Dictionary(); TransactionalAction.Run( - action: () => { + action: () => + { try { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var tempPath = Path.Combine(_fileSystem.Directory.CreateTemporarySubdirectory(), Path.GetRandomFileName()); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); files[file.Value] = tempPath; } @@ -118,13 +120,15 @@ public void RemoveShim(ToolCommandName commandName) ex); } }, - commit: () => { + commit: () => + { foreach (var value in files.Values) { _fileSystem.File.Delete(value); } }, - rollback: () => { + rollback: () => + { foreach (var kvp in files) { FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(kvp.Value, kvp.Key)); diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 799c99fbec39..8b04671a631b 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -3,11 +3,9 @@ using System; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using System.Linq; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools.Common; using NuGet.Common; using NuGet.Configuration; @@ -18,8 +16,6 @@ namespace Microsoft.DotNet.Cli /// public static class SudoEnvironmentDirectoryOverride { - private const string SudoHomeDirectory = "/tmp/dotnet_sudo_home/"; - /// /// Not for security use. Detect if command is running under sudo /// via if SUDO_UID being set. @@ -38,22 +34,9 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { - if (!TempHomeIsOnlyRootWritable(SudoHomeDirectory)) - { - try - { - Directory.Delete(SudoHomeDirectory, recursive: true); - } - catch (DirectoryNotFoundException) - { - // Avoid read after write race condition - } - } - - Directory.CreateDirectory(SudoHomeDirectory); - + string sudoHome = PathUtilities.CreateTempSubdirectory(); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); - Environment.SetEnvironmentVariable("HOME", SudoHomeDirectory); + Environment.SetEnvironmentVariable("HOME", sudoHome); CopyUserNuGetConfigToOverriddenHome(homeBeforeOverride); } @@ -107,31 +90,5 @@ private static void CopyUserNuGetConfigToOverriddenHome(string homeBeforeOverrid private static bool IsRunningWorkloadCommand(ParseResult parseResult) => parseResult.RootSubCommandResult() == (WorkloadCommandParser.GetCommand().Name); - - private static bool TempHomeIsOnlyRootWritable(string path) - { - if (StatInterop.LStat(path, out StatInterop.FileStatus fileStat) != 0) - { - return false; - } - - return IsOwnedByRoot(fileStat) && GroupCannotWrite(fileStat) && - OtherUserCannotWrite(fileStat); - } - - private static bool OtherUserCannotWrite(StatInterop.FileStatus fileStat) - { - return (fileStat.Mode & (int) StatInterop.Permissions.S_IWOTH) == 0; - } - - private static bool GroupCannotWrite(StatInterop.FileStatus fileStat) - { - return (fileStat.Mode & (int) StatInterop.Permissions.S_IWGRP) == 0; - } - - private static bool IsOwnedByRoot(StatInterop.FileStatus fileStat) - { - return fileStat.Uid == 0; - } } } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 1f3a37d9ee0f..f9d20bf96648 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -11,7 +11,6 @@ using Microsoft.DotNet.Configurer; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; -using NuGet.ProjectModel; using NuGet.Versioning; namespace Microsoft.DotNet.ToolPackage @@ -46,17 +45,18 @@ public IToolPackage InstallPackage( string rollbackDirectory = null; return TransactionalAction.Run( - action: () => { + action: () => + { try { var stageDirectory = _store.GetRandomStagingDirectory(); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - var tempProject = CreateTempProject( + string tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, - targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, + targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, restoreDirectory: stageDirectory, assetJsonOutputDirectory: stageDirectory, rootConfigDirectory: packageLocation.RootConfigDirectory, @@ -65,13 +65,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProject), packageLocation, verbosity: verbosity); } finally { - File.Delete(tempProject.Value); + File.Delete(tempProject); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -104,7 +104,8 @@ public IToolPackage InstallPackage( ex); } }, - rollback: () => { + rollback: () => + { if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory)) { Directory.Delete(rollbackDirectory, true); @@ -126,16 +127,13 @@ public IToolPackage InstallPackageToExternalManagedLocation( string targetFramework = null, string verbosity = null) { - var tempDirectoryForAssetJson = new DirectoryPath(Path.GetTempPath()) - .WithSubDirectories(Path.GetRandomFileName()); - - Directory.CreateDirectory(tempDirectoryForAssetJson.Value); + var tempDirectoryForAssetJson = PathUtilities.CreateTempSubdirectory(); - var tempProject = CreateTempProject( + string tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, - assetJsonOutputDirectory: tempDirectoryForAssetJson, + assetJsonOutputDirectory: new DirectoryPath(tempDirectoryForAssetJson), restoreDirectory: null, rootConfigDirectory: packageLocation.RootConfigDirectory, additionalFeeds: packageLocation.AdditionalFeeds); @@ -143,19 +141,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProject), packageLocation, verbosity: verbosity); } finally { - File.Delete(tempProject.Value); + File.Delete(tempProject); } - return ToolPackageInstance.CreateFromAssetFile(packageId, tempDirectoryForAssetJson); + return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private FilePath CreateTempProject( + private string CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -164,16 +162,14 @@ private FilePath CreateTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - var tempProject = _tempProject ?? new DirectoryPath(Path.GetTempPath()) - .WithSubDirectories(Path.GetRandomFileName()) - .WithFile("restore.csproj"); - - if (Path.GetExtension(tempProject.Value) != "csproj") + string tempProject; + if (_tempProject != null && _tempProject.HasValue) { - tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); + tempProject = _tempProject.Value.Value; + Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); } - - Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + else + tempProject = Path.Combine(PathUtilities.CreateTempSubdirectory(), "restore.csproj"); var tempProjectContent = new XDocument( new XElement("Project", @@ -203,7 +199,7 @@ private FilePath CreateTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject.Value, tempProjectContent.ToString()); + File.WriteAllText(tempProject, tempProjectContent.ToString()); return tempProject; } diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 7e06aae182b1..0b4c199f1b3e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -72,7 +71,7 @@ public ToolInstallGlobalOrToolPathCommand( _environmentPathInstruction = environmentPathInstruction ?? EnvironmentPathFactory.CreateEnvironmentPathInstruction(); _createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository; - var tempDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-tool-install")); + var tempDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); var configOption = parseResult.GetValueForOption(ToolInstallCommandParser.ConfigOption); var sourceOption = parseResult.GetValueForOption(ToolInstallCommandParser.AddSourceOption); var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption); @@ -143,7 +142,7 @@ public override int Execute() } else { - framework = string.IsNullOrEmpty(_framework) ? + framework = string.IsNullOrEmpty(_framework) ? null : NuGetFramework.Parse(_framework); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index 92478a0b64b0..dc51124d0845 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; @@ -104,7 +103,7 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : Path.GetTempPath(); + : PathUtilities.CreateTempSubdirectory(); TempPackagesDirectory = new DirectoryPath(Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 77c5a6acbbf0..34257aa40ac1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -5,19 +5,18 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Configurer; using Microsoft.DotNet.ToolPackage; +using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; using NuGet.Versioning; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; -using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; -using System.Text.Json; -using System.Threading.Tasks; namespace Microsoft.DotNet.Workloads.Workload.Install { @@ -51,7 +50,7 @@ public FileBasedInstaller(IReporter reporter, { _userProfileDir = userProfileDir; _dotnetDir = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); - _tempPackagesDir = new DirectoryPath(tempDirPath ?? Path.GetTempPath()); + _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); ILogger logger = verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger(); _restoreActionConfig = restoreActionConfig; _nugetPackageDownloader = nugetPackageDownloader ?? @@ -188,7 +187,7 @@ public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand Directory.Delete(dir, true); } } - }); + }); } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 13c6f1ea8a33..db42c3dc497a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -116,7 +115,7 @@ public void GarbageCollectInstalledWorkloadPacks(DirectoryPath? offlineCache = n Log?.LogMessage("Starting garbage collection."); IEnumerable installedFeatureBands = GetInstalledFeatureBands(); IEnumerable installedWorkloads = RecordRepository.GetInstalledWorkloads(_sdkFeatureBand); - Dictionary<(WorkloadPackId id, string version),PackInfo> expectedWorkloadPacks = installedWorkloads + Dictionary<(WorkloadPackId id, string version), PackInfo> expectedWorkloadPacks = installedWorkloads .SelectMany(workload => _workloadResolver.GetPacksInWorkload(workload)) .Distinct() .Select(pack => _workloadResolver.TryGetPackInfo(pack)) @@ -415,9 +414,9 @@ public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand RollBackMsiInstall(msiToInstall); } }); - + } - + } void RollBackMsiInstall(WorkloadDownload msiToRollback, DirectoryPath? offlineCache = null) @@ -492,17 +491,10 @@ public PackageId GetManifestPackageId(ManifestId manifestId, SdkFeatureBand feat public async Task ExtractManifestAsync(string nupkgPath, string targetPath) { Log?.LogMessage($"ExtractManifestAsync: Extracting '{nupkgPath}' to '{targetPath}'"); - - string extractionPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - if (Directory.Exists(extractionPath)) - { - Directory.Delete(extractionPath, true); - } + string extractionPath = PathUtilities.CreateTempSubdirectory(); try { - Directory.CreateDirectory(extractionPath); - Log?.LogMessage($"ExtractManifestAsync: Temporary extraction path: '{extractionPath}'"); await _nugetPackageDownloader.ExtractPackageAsync(nupkgPath, new DirectoryPath(extractionPath)); if (Directory.Exists(targetPath)) @@ -789,7 +781,7 @@ private string ExtractPackage(string packageId, string packageVersion, Directory // Extract the contents to a random folder to avoid potential file injection/hijacking // shenanigans before moving it to the final cache directory. - string extractionDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + string extractionDirectory = PathUtilities.CreateTempSubdirectory(); Directory.CreateDirectory(extractionDirectory); Log?.LogMessage($"Extracting '{packageId}' to '{extractionDirectory}'"); _ = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(extractionDirectory)).Result; @@ -959,7 +951,7 @@ public static NetSdkMsiInstallerClient Create( if (nugetPackageDownloader == null) { - DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? Path.GetTempPath() : tempDirPath); + DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? PathUtilities.CreateTempSubdirectory() : tempDirPath); nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(tempPackagesDir), diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 5a86a6959356..95834b1f4832 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using System.Net.Http; -using System.Runtime.InteropServices; using System.Text.Json; using System.Threading.Tasks; using Microsoft.DotNet.Cli; @@ -69,7 +68,7 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) var sdkVersion = Product.Version; var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); - var tempPackagesDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-sdk-advertising-temp")); + var tempPackagesDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); var nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(tempPackagesDir, new NullLogger()), @@ -189,9 +188,9 @@ Dictionary Workloads } if (advertisingManifestVersionAndWorkloads != null && - ((advertisingManifestVersionAndWorkloads.Value.ManifestVersion.CompareTo(currentManifestVersion.manifestVersion) > 0 + ((advertisingManifestVersionAndWorkloads.Value.ManifestVersion.CompareTo(currentManifestVersion.manifestVersion) > 0 && advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.Equals(currentManifestVersion.sdkFeatureBand)) || - advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.CompareTo(currentManifestVersion.sdkFeatureBand) > 0)) + advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.CompareTo(currentManifestVersion.sdkFeatureBand) > 0)) { manifestUpdates.Add((new ManifestVersionUpdate(manifestId, currentManifestVersion.manifestVersion, currentManifestVersion.sdkFeatureBand.ToString(), advertisingManifestVersionAndWorkloads.Value.ManifestVersion, advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.ToString()), @@ -262,7 +261,7 @@ public async Task> GetManifestPackageDownloadsAsyn var newPackageId = _workloadManifestInstaller.GetManifestPackageId(new ManifestId(manifest.Id), installedSdkFeatureBand); (success, latestVersion) = await GetPackageVersion(newPackageId, packageSourceLocation: _packageSourceLocation, includePreview: includePreviews); - + if (success) { downloads.Add(new WorkloadDownload(manifest.Id, newPackageId.ToString(), latestVersion.ToString())); @@ -307,7 +306,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, try { var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId); - + bool success; (success, packagePath) = await GetManifestPackageUpdate(_sdkFeatureBand, manifestId, includePreviews, offlineCache); if (!success) @@ -323,7 +322,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId)); return; } - + await _workloadManifestInstaller.ExtractManifestAsync(packagePath, adManifestPath); // add file that contains the advertisted manifest feature band so GetAdvertisingManifestVersionAndWorkloads will use correct feature band, regardless of if rollback occurred or not @@ -384,7 +383,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, { adManifestFeatureBand = new SdkFeatureBand(File.ReadAllText(adManifestFeatureBandPath)); } - + return (new ManifestVersion(manifest.Version), adManifestFeatureBand, manifest.Workloads.Values.OfType().ToDictionary(w => w.Id)); } @@ -470,12 +469,12 @@ private async Task NewerManifestPackageExists(ManifestId manifest) ManifestVersion manifestVersion; SdkFeatureBand manifestFeatureBand; var parts = manifest.Value.Split('/'); - + string manifestVersionString = (parts[0]); if (!FXVersion.TryParse(manifestVersionString, out FXVersion version)) { throw new FormatException(String.Format(LocalizableStrings.InvalidVersionForWorkload, manifest.Key, manifestVersionString)); - } + } manifestVersion = new ManifestVersion(parts[0]); if (parts.Length == 1) @@ -499,15 +498,15 @@ private bool BackgroundUpdatesAreDisabled() => private static string GetAdvertisingWorkloadsFilePath(string userProfileDir, SdkFeatureBand featureBand) => Path.Combine(userProfileDir, $".workloadAdvertisingUpdates{featureBand}"); - private async Task GetOnlinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews) - { - string packagePath = await _nugetPackageDownloader.DownloadPackageAsync( - _workloadManifestInstaller.GetManifestPackageId(manifestId, sdkFeatureBand), - packageSourceLocation: _packageSourceLocation, - includePreview: includePreviews); - - return packagePath; - } + private async Task GetOnlinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews) + { + string packagePath = await _nugetPackageDownloader.DownloadPackageAsync( + _workloadManifestInstaller.GetManifestPackageId(manifestId, sdkFeatureBand), + packageSourceLocation: _packageSourceLocation, + includePreview: includePreviews); + + return packagePath; + } private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, DirectoryPath? offlineCache = null) { @@ -527,7 +526,7 @@ private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId m { if (offlineCache == null || !offlineCache.HasValue) { - try + try { string packagePath = await GetOnlinePackagePath(sdkFeatureBand, manifestId, includePreviews); return (true, packagePath); @@ -557,9 +556,9 @@ private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId m } } - -private string GetAdvertisingManifestPath(SdkFeatureBand featureBand, ManifestId manifestId) => - Path.Combine(_userProfileDir, "sdk-advertising", featureBand.ToString(), manifestId.ToString()); + + private string GetAdvertisingManifestPath(SdkFeatureBand featureBand, ManifestId manifestId) => + Path.Combine(_userProfileDir, "sdk-advertising", featureBand.ToString(), manifestId.ToString()); } } diff --git a/src/Common/PathUtilities.cs b/src/Common/PathUtilities.cs new file mode 100644 index 000000000000..3dd303a6c4ec --- /dev/null +++ b/src/Common/PathUtilities.cs @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#nullable disable + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Microsoft.DotNet; + +static class PathUtilities +{ + const int S_IRUSR = 256; + const int S_IWUSR = 128; + const int S_IXUSR = 64; + const int S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR; // 700 (octal) Permissions + + const int MAX_NUM_DIRECTORY_CREATE_RETRIES = 2; + + public static string CreateTempSubdirectory() + { + return CreateTempSubdirectoryRetry(0); + } + + [DllImport("libc", SetLastError = true)] + private static extern int mkdir(string pathname, int mode); + private static string CreateTempSubdirectoryRetry(int attemptNo) + { + string path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + int mkdirStatusCode = mkdir(path, S_IRWXU); + if (mkdirStatusCode != 0) + { + int errno = Marshal.GetLastWin32Error(); + if (Directory.Exists(path) && attemptNo < MAX_NUM_DIRECTORY_CREATE_RETRIES) + { + return CreateTempSubdirectoryRetry(attemptNo + 1); + } + else + throw new IOException($"Failed to create a temporary subdirectory {path} with mkdir, error code: {errno}"); + } + } + else + { + Directory.CreateDirectory(path); + } + return path; + } +} diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index e3d4644c243f..eb0f35b339f3 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -32,6 +32,5 @@ public static Version TryGetAssemblyVersion(string sourcePath) return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; } - } } diff --git a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs index 843f882ffdb6..31cbcfe77881 100644 --- a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs +++ b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs @@ -26,7 +26,7 @@ public GivenAFirstTimeUseNoticeSentinel() _fileSystemMockBuilder = FileSystemMockBuilder.Create(); } - [Fact(Skip ="Product.Version not set correctly when running tests")] + [Fact(Skip = "Product.Version not set correctly when running tests")] public void TheSentinelHasTheCurrentVersionInItsName() { FirstTimeUseNoticeSentinel.SENTINEL.Should().Contain($"{Product.Version}"); @@ -174,6 +174,11 @@ public ITemporaryDirectory CreateTemporaryDirectory() throw new NotImplementedException(); } + public string CreateTemporarySubdirectory() + { + throw new NotImplementedException(); + } + public IEnumerable EnumerateDirectories(string path) { throw new NotImplementedException(); diff --git a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs index 10e3f1930814..6802977214b2 100644 --- a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs +++ b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs @@ -173,6 +173,11 @@ public IEnumerable EnumerateFileSystemEntries(string path) throw new UnauthorizedAccessException(); } + public string CreateTemporarySubdirectory() + { + throw new NotImplementedException(); + } + public string GetCurrentDirectory() { throw new NotImplementedException(); diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs index e2593cc86abb..138d87890b1d 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs @@ -1059,7 +1059,7 @@ private static string GetTestLocalFeedPath() => private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker(); private const string TestPackageVersion = "1.0.4"; private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo"); - private static readonly IEnumerable TestFrameworks = new NuGetFramework[] { NuGetFramework.Parse("netcoreapp2.1")}; + private static readonly IEnumerable TestFrameworks = new NuGetFramework[] { NuGetFramework.Parse("netcoreapp2.1") }; public ToolPackageInstallerTests(ITestOutputHelper log) : base(log) { diff --git a/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs b/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs index 7eb9e5381989..0c47207c56f5 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs @@ -154,7 +154,7 @@ public void CreateDirectory(string path) else { DirectoryNode directoryNode = new DirectoryNode(); - directoryNode = (DirectoryNode) current.Subs.GetOrAdd(p , directoryNode); + directoryNode = (DirectoryNode)current.Subs.GetOrAdd(p, directoryNode); current = directoryNode; } } @@ -237,7 +237,7 @@ public DirectoryNode GetParentOfDirectoryNode(string path) } PathModel pathModel = CreateFullPathModel(path); - if (current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node) ) + if (current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node)) { if (node is FileNode) { @@ -283,7 +283,7 @@ public PathModel(string path) } string[] pathArray = path.Split( - new[] {directorySeparatorChar, altDirectorySeparatorChar}, + new[] { directorySeparatorChar, altDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); Volume = volume; PathArray = pathArray; @@ -451,7 +451,7 @@ public void Move(string source, string destination) if (_files.TryGetNodeParent(destination, out DirectoryNode current) && current != null) { - sourceFileNode = (FileNode) current.Subs.GetOrAdd(new PathModel(destination).FileOrDirectoryName(), sourceFileNode); + sourceFileNode = (FileNode)current.Subs.GetOrAdd(new PathModel(destination).FileOrDirectoryName(), sourceFileNode); sourceParent.Subs.TryRemove(new PathModel(source).FileOrDirectoryName(), out _); } else @@ -525,9 +525,9 @@ public bool Exists(string path) if (_files.TryGetNodeParent(path, out DirectoryNode current)) { - PathModel pathModel = new PathModel(path); + PathModel pathModel = new PathModel(path); - return current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node) + return current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node) && node is DirectoryNode; } @@ -579,6 +579,11 @@ public void CreateDirectory(string path) _files.CreateDirectory(path); } + public string CreateTemporarySubdirectory() + { + return CreateTemporaryDirectory().DirectoryPath; + } + public void Delete(string path, bool recursive) { if (path == null) throw new ArgumentNullException(nameof(path));