dotnet-installer/test/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageInstallerMock.cs
William Li b0ee5db411
consume bring your own shim(byos) (#9018)
If there are shims packaged by convention in nupkg. Shim Repository will simply copy it to the right location.

The query interface ToolPackageInstance will be in charge of finding the shim folder and filter the right RID. Shim Repository will pick the right file after the folder is located since Shim Repository knows the shim name and it also book keep the files at uninstallation.
During development, due to the wrong adapter level. The mock duplicated too much logic. So, I corrected the abstraction level to lower (only create shim). And replaced the existing mock with a much smaller one without any atomic control and file move, copy logic. At the same time. The chmod, which is a IO action, causes problem during tests. So I added adapter layer to it and put it in Util.
2018-04-10 15:42:50 -07:00

116 lines
5.3 KiB
C#

// 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 System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Transactions;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.ToolPackage;
using Microsoft.DotNet.Tools;
using Microsoft.Extensions.EnvironmentAbstractions;
using NuGet.Versioning;
namespace Microsoft.DotNet.Tools.Tests.ComponentMocks
{
internal class ToolPackageInstallerMock : IToolPackageInstaller
{
private const string ProjectFileName = "TempProject.csproj";
private readonly IToolPackageStore _store;
private readonly IProjectRestorer _projectRestorer;
private readonly IFileSystem _fileSystem;
private readonly Action _installCallback;
private readonly Dictionary<PackageId, IEnumerable<string>> _warningsMap;
private readonly Dictionary<PackageId, IReadOnlyList<FilePath>> _packagedShimsMap;
public ToolPackageInstallerMock(
IFileSystem fileSystem,
IToolPackageStore store,
IProjectRestorer projectRestorer,
Action installCallback = null,
Dictionary<PackageId, IEnumerable<string>> warningsMap = null,
Dictionary<PackageId, IReadOnlyList<FilePath>> packagedShimsMap = null)
{
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_store = store ?? throw new ArgumentNullException(nameof(store));
_projectRestorer = projectRestorer ?? throw new ArgumentNullException(nameof(projectRestorer));
_installCallback = installCallback;
_warningsMap = warningsMap ?? new Dictionary<PackageId, IEnumerable<string>>();
_packagedShimsMap = packagedShimsMap ?? new Dictionary<PackageId, IReadOnlyList<FilePath>>();
}
public IToolPackage InstallPackage(PackageId packageId,
VersionRange versionRange = null,
string targetFramework = null,
FilePath? nugetConfig = null,
DirectoryPath? rootConfigDirectory = null,
string[] additionalFeeds = null,
string verbosity = null)
{
var packageRootDirectory = _store.GetRootPackageDirectory(packageId);
string rollbackDirectory = null;
return TransactionalAction.Run<IToolPackage>(
action: () => {
var stageDirectory = _store.GetRandomStagingDirectory();
_fileSystem.Directory.CreateDirectory(stageDirectory.Value);
rollbackDirectory = stageDirectory.Value;
var tempProject = new FilePath(Path.Combine(stageDirectory.Value, ProjectFileName));
// Write a fake project with the requested package id, version, and framework
_fileSystem.File.WriteAllText(
tempProject.Value,
$"{packageId}:{versionRange?.ToString("S", new VersionRangeFormatter()) ?? "*"}:{targetFramework}");
// Perform a restore on the fake project
_projectRestorer.Restore(
tempProject,
stageDirectory,
nugetConfig,
verbosity);
if (_installCallback != null)
{
_installCallback();
}
var version = _store.GetStagedPackageVersion(stageDirectory, packageId);
var packageDirectory = _store.GetPackageDirectory(packageId, version);
if (_fileSystem.Directory.Exists(packageDirectory.Value))
{
throw new ToolPackageException(
string.Format(
CommonLocalizableStrings.ToolPackageConflictPackageId,
packageId,
version.ToNormalizedString()));
}
_fileSystem.Directory.CreateDirectory(packageRootDirectory.Value);
_fileSystem.Directory.Move(stageDirectory.Value, packageDirectory.Value);
rollbackDirectory = packageDirectory.Value;
IEnumerable<string> warnings = null;
_warningsMap.TryGetValue(packageId, out warnings);
IReadOnlyList<FilePath> packedShims = null;
_packagedShimsMap.TryGetValue(packageId, out packedShims);
return new ToolPackageMock(_fileSystem, packageId, version, packageDirectory, warnings: warnings, packagedShims: packedShims);
},
rollback: () => {
if (rollbackDirectory != null && _fileSystem.Directory.Exists(rollbackDirectory))
{
_fileSystem.Directory.Delete(rollbackDirectory, true);
}
if (_fileSystem.Directory.Exists(packageRootDirectory.Value) &&
!_fileSystem.Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any())
{
_fileSystem.Directory.Delete(packageRootDirectory.Value, false);
}
});
}
}
}