Tool produces a 0-byte binary when compilation fails

Fixes #35
This commit is contained in:
Pranav K 2016-11-21 12:33:39 -08:00
parent 54234480f5
commit 172f0579d5
2 changed files with 55 additions and 8 deletions

View File

@ -9,7 +9,6 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.CodeAnalysis;
@ -104,7 +103,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Design.Internal
var resources = GetResources(results);
var assemblyPath = Path.Combine(OutputPathOption.Value(), precompileAssemblyName + ".dll");
var emitResult = EmitAssembly(compilation, assemblyPath, resources);
var emitResult = EmitAssembly(
compilation,
MvcServiceProvider.Compiler.EmitOptions,
assemblyPath,
resources);
if (!emitResult.Success)
{
@ -143,23 +146,41 @@ namespace Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Design.Internal
return resources;
}
private EmitResult EmitAssembly(
public EmitResult EmitAssembly(
CSharpCompilation compilation,
EmitOptions emitOptions,
string assemblyPath,
ResourceDescription[] resources)
{
Directory.CreateDirectory(Path.GetDirectoryName(assemblyPath));
EmitResult emitResult;
using (var assemblyStream = File.OpenWrite(assemblyPath))
using (var assemblyStream = new MemoryStream())
{
using (var pdbStream = File.OpenWrite(Path.ChangeExtension(assemblyPath, ".pdb")))
using (var pdbStream = new MemoryStream())
{
emitResult = compilation.Emit(
assemblyStream,
pdbStream,
manifestResources: resources,
options: MvcServiceProvider.Compiler.EmitOptions);
options: emitOptions);
if (emitResult.Success)
{
Directory.CreateDirectory(Path.GetDirectoryName(assemblyPath));
var pdbPath = Path.ChangeExtension(assemblyPath, ".pdb");
assemblyStream.Position = 0;
pdbStream.Position = 0;
// Avoid writing to disk unless the compilation is successful.
using (var assemblyFileStream = File.OpenWrite(assemblyPath))
{
assemblyStream.CopyTo(assemblyFileStream);
}
using (var pdbFileStream = File.OpenWrite(pdbPath))
{
pdbStream.CopyTo(pdbFileStream);
}
}
}
}

View File

@ -6,6 +6,9 @@ using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Design.Internal;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Tools
@ -150,6 +153,29 @@ Options:
Assert.Equal(expectedError, result.Error.Trim());
}
[Fact]
public void EmitAssembly_DoesNotWriteAssembliesToDisk_IfCompilationFails()
{
// Arrange
var assemblyDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var assemblyPath = Path.Combine(assemblyDirectory, "out.dll");
var precompileRunCommand = new PrecompileRunCommand();
var syntaxTree = CSharpSyntaxTree.ParseText("using Microsoft.DoestNotExist");
var compilation = CSharpCompilation.Create("Test.dll", new[] { syntaxTree });
// Act
var emitResult = precompileRunCommand.EmitAssembly(
compilation,
new EmitOptions(),
assemblyPath,
new ResourceDescription[0]);
// Assert
Assert.False(emitResult.Success);
Assert.False(Directory.Exists(assemblyDirectory));
Assert.False(File.Exists(assemblyPath));
}
private static string GetToolVersion()
{
return typeof(Program)