2018-01-28 13:35:04 -08:00
// 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 ;
2018-02-22 19:13:36 -08:00
using NuGet.Versioning ;
2018-01-28 13:35:04 -08:00
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 ;
2018-03-26 12:50:09 -07:00
private readonly Dictionary < PackageId , IEnumerable < string > > _warningsMap ;
2018-04-10 15:42:50 -07:00
private readonly Dictionary < PackageId , IReadOnlyList < FilePath > > _packagedShimsMap ;
2018-01-28 13:35:04 -08:00
public ToolPackageInstallerMock (
IFileSystem fileSystem ,
IToolPackageStore store ,
IProjectRestorer projectRestorer ,
2018-03-26 12:50:09 -07:00
Action installCallback = null ,
2018-04-10 15:42:50 -07:00
Dictionary < PackageId , IEnumerable < string > > warningsMap = null ,
Dictionary < PackageId , IReadOnlyList < FilePath > > packagedShimsMap = null )
2018-01-28 13:35:04 -08:00
{
_fileSystem = fileSystem ? ? throw new ArgumentNullException ( nameof ( fileSystem ) ) ;
_store = store ? ? throw new ArgumentNullException ( nameof ( store ) ) ;
_projectRestorer = projectRestorer ? ? throw new ArgumentNullException ( nameof ( projectRestorer ) ) ;
_installCallback = installCallback ;
2018-03-26 12:50:09 -07:00
_warningsMap = warningsMap ? ? new Dictionary < PackageId , IEnumerable < string > > ( ) ;
2018-04-10 15:42:50 -07:00
_packagedShimsMap = packagedShimsMap ? ? new Dictionary < PackageId , IReadOnlyList < FilePath > > ( ) ;
2018-01-28 13:35:04 -08:00
}
2018-03-19 22:22:45 -07:00
public IToolPackage InstallPackage ( PackageId packageId ,
2018-02-22 19:13:36 -08:00
VersionRange versionRange = null ,
2018-01-28 13:35:04 -08:00
string targetFramework = null ,
FilePath ? nugetConfig = null ,
2018-03-07 01:30:18 -08:00
DirectoryPath ? rootConfigDirectory = null ,
2018-03-19 22:22:45 -07:00
string [ ] additionalFeeds = null ,
2018-01-28 13:35:04 -08:00
string verbosity = null )
{
2018-02-22 19:13:36 -08:00
var packageRootDirectory = _store . GetRootPackageDirectory ( packageId ) ;
2018-01-28 13:35:04 -08:00
string rollbackDirectory = null ;
return TransactionalAction . Run < IToolPackage > (
action : ( ) = > {
2018-02-22 19:13:36 -08:00
var stageDirectory = _store . GetRandomStagingDirectory ( ) ;
2018-01-28 13:35:04 -08:00
_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 ,
2018-04-24 10:19:27 -07:00
$"{packageId};{versionRange?.ToString(" S ", new VersionRangeFormatter()) ?? " * "};{targetFramework};{stageDirectory.Value}" ) ;
2018-01-28 13:35:04 -08:00
// Perform a restore on the fake project
_projectRestorer . Restore (
tempProject ,
nugetConfig ,
verbosity ) ;
if ( _installCallback ! = null )
{
_installCallback ( ) ;
}
2018-02-22 19:13:36 -08:00
var version = _store . GetStagedPackageVersion ( stageDirectory , packageId ) ;
var packageDirectory = _store . GetPackageDirectory ( packageId , version ) ;
2018-01-28 13:35:04 -08:00
if ( _fileSystem . Directory . Exists ( packageDirectory . Value ) )
{
throw new ToolPackageException (
string . Format (
CommonLocalizableStrings . ToolPackageConflictPackageId ,
packageId ,
2018-02-22 19:13:36 -08:00
version . ToNormalizedString ( ) ) ) ;
2018-01-28 13:35:04 -08:00
}
_fileSystem . Directory . CreateDirectory ( packageRootDirectory . Value ) ;
_fileSystem . Directory . Move ( stageDirectory . Value , packageDirectory . Value ) ;
rollbackDirectory = packageDirectory . Value ;
2018-03-26 12:50:09 -07:00
IEnumerable < string > warnings = null ;
_warningsMap . TryGetValue ( packageId , out warnings ) ;
2018-04-10 15:42:50 -07:00
IReadOnlyList < FilePath > packedShims = null ;
_packagedShimsMap . TryGetValue ( packageId , out packedShims ) ;
return new ToolPackageMock ( _fileSystem , packageId , version , packageDirectory , warnings : warnings , packagedShims : packedShims ) ;
2018-01-28 13:35:04 -08:00
} ,
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 ) ;
}
} ) ;
}
}
}