2018-01-24 10:16:27 -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 ;
2018-02-06 13:38:06 -08:00
using System.Collections.Generic ;
2018-01-24 10:16:27 -08:00
using System.IO ;
2018-02-06 13:38:06 -08:00
using System.Runtime.InteropServices ;
using System.Transactions ;
using Microsoft.DotNet.Cli ;
2018-01-24 10:16:27 -08:00
using Microsoft.DotNet.Cli.Utils ;
using Microsoft.DotNet.ShellShim ;
using Microsoft.Extensions.EnvironmentAbstractions ;
using Newtonsoft.Json ;
namespace Microsoft.DotNet.Tools.Tests.ComponentMocks
{
internal class ShellShimMakerMock : IShellShimMaker
{
private static IFileSystem _fileSystem ;
private readonly string _pathToPlaceShim ;
public ShellShimMakerMock ( string pathToPlaceShim , IFileSystem fileSystem = null )
{
_pathToPlaceShim =
2018-02-06 13:38:06 -08:00
pathToPlaceShim ? ?
throw new ArgumentNullException ( nameof ( pathToPlaceShim ) ) ;
2018-01-24 10:16:27 -08:00
_fileSystem = fileSystem ? ? new FileSystemWrapper ( ) ;
}
2018-02-06 13:38:06 -08:00
public void EnsureCommandNameUniqueness ( string shellCommandName )
{
if ( _fileSystem . File . Exists ( GetShimPath ( shellCommandName ) . Value ) )
{
throw new GracefulException (
string . Format ( CommonLocalizableStrings . FailInstallToolSameName ,
shellCommandName ) ) ;
}
}
2018-01-30 15:41:39 -08:00
public void CreateShim ( FilePath packageExecutable , string shellCommandName )
2018-02-06 13:38:06 -08:00
{
var createShimTransaction = new CreateShimTransaction (
createShim : locationOfShimDuringTransaction = >
{
EnsureCommandNameUniqueness ( shellCommandName ) ;
PlaceShim ( packageExecutable , shellCommandName , locationOfShimDuringTransaction ) ;
} ,
rollback : locationOfShimDuringTransaction = >
{
foreach ( FilePath f in locationOfShimDuringTransaction )
{
if ( File . Exists ( f . Value ) )
{
File . Delete ( f . Value ) ;
}
}
} ) ;
using ( var transactionScope = new TransactionScope ( ) )
{
Transaction . Current . EnlistVolatile ( createShimTransaction , EnlistmentOptions . None ) ;
createShimTransaction . CreateShim ( ) ;
transactionScope . Complete ( ) ;
}
}
public void Remove ( string shellCommandName )
{
File . Delete ( GetShimPath ( shellCommandName ) . Value ) ;
}
private void PlaceShim ( FilePath packageExecutable , string shellCommandName , List < FilePath > locationOfShimDuringTransaction )
2018-01-24 10:16:27 -08:00
{
var fakeshim = new FakeShim
{
Runner = "dotnet" ,
ExecutablePath = packageExecutable . Value
} ;
var script = JsonConvert . SerializeObject ( fakeshim ) ;
2018-02-06 13:38:06 -08:00
FilePath scriptPath = GetShimPath ( shellCommandName ) ;
2018-01-24 10:16:27 -08:00
_fileSystem . File . WriteAllText ( scriptPath . Value , script ) ;
2018-02-06 13:38:06 -08:00
locationOfShimDuringTransaction . Add ( scriptPath ) ;
2018-01-24 10:16:27 -08:00
}
2018-02-06 13:38:06 -08:00
private FilePath GetShimPath ( string shellCommandName )
2018-01-24 10:16:27 -08:00
{
2018-02-06 13:38:06 -08:00
var scriptPath = Path . Combine ( _pathToPlaceShim , shellCommandName ) ;
if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
2018-01-24 10:16:27 -08:00
{
2018-02-06 13:38:06 -08:00
scriptPath + = ".exe" ;
2018-01-24 10:16:27 -08:00
}
2018-02-06 13:38:06 -08:00
return new FilePath ( scriptPath ) ;
2018-01-24 10:16:27 -08:00
}
public class FakeShim
{
public string Runner { get ; set ; }
public string ExecutablePath { get ; set ; }
}
}
}