Execute 'csc' with working directory set to the project directory.

When using a ruleset with a relative path in buildOptions, csc can't
find the file because it is not working in the same directory as the
project.

Fix #2710
This commit is contained in:
Eric Erhardt 2016-04-29 22:19:35 -05:00
parent 2827ef208a
commit f2d917ed2e
10 changed files with 99 additions and 7 deletions

View file

@ -0,0 +1,26 @@
// 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.IO;
namespace TestLibrary
{
public class AttributeWithoutUsage : Attribute
{
}
public class ClassWithUndisposedStream
{
private Stream _nonDisposedStream = new MemoryStream();
public ClassWithUndisposedStream()
{
}
public Stream GetStream()
{
return _nonDisposedStream;
}
}
}

View file

@ -0,0 +1,16 @@
{
"version": "1.0.0-*",
"buildOptions": {
"additionalArguments": [ "/ruleset:../global.ruleset" ]
},
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027",
"System.Runtime.Analyzers": {
"version": "1.1.0",
"type": "build"
}
},
"frameworks": {
"netstandard1.5": {}
}
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="14.0">
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1018" Action="Hidden" />
</Rules>
</RuleSet>

View file

@ -20,6 +20,7 @@ namespace Microsoft.DotNet.Cli.Utils
private readonly Func<string[], int> _builtInCommand;
private readonly StreamForwarder _stdOut;
private readonly StreamForwarder _stdErr;
private string _workingDirectory;
public string CommandName { get; }
public string CommandArgs => string.Join(" ", _commandArgs);
@ -38,6 +39,7 @@ namespace Microsoft.DotNet.Cli.Utils
{
TextWriter originalConsoleOut = Console.Out;
TextWriter originalConsoleError = Console.Error;
string originalWorkingDirectory = Directory.GetCurrentDirectory();
try
{
@ -52,6 +54,11 @@ namespace Microsoft.DotNet.Cli.Utils
// Reset the Reporters to the new Console Out and Error.
Reporter.Reset();
if (!string.IsNullOrEmpty(_workingDirectory))
{
Directory.SetCurrentDirectory(_workingDirectory);
}
var taskOut = _stdOut.BeginRead(new StreamReader(outStream));
var taskErr = _stdErr.BeginRead(new StreamReader(errorStream));
@ -71,6 +78,7 @@ namespace Microsoft.DotNet.Cli.Utils
{
Console.SetOut(originalConsoleOut);
Console.SetError(originalConsoleError);
Directory.SetCurrentDirectory(originalWorkingDirectory);
Reporter.Reset();
}
@ -100,6 +108,13 @@ namespace Microsoft.DotNet.Cli.Utils
return this;
}
public ICommand WorkingDirectory(string workingDirectory)
{
_workingDirectory = workingDirectory;
return this;
}
public CommandResolutionStrategy ResolutionStrategy
{
get
@ -132,10 +147,5 @@ namespace Microsoft.DotNet.Cli.Utils
{
throw new NotImplementedException();
}
public ICommand WorkingDirectory(string projectDirectory)
{
throw new NotImplementedException();
}
}
}

View file

@ -84,6 +84,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Csc
// Execute CSC!
var result = RunCsc(new string[] { $"-noconfig", "@" + $"{rsp}" })
.WorkingDirectory(Directory.GetCurrentDirectory())
.ForwardStdErr()
.ForwardStdOut()
.Execute();

View file

@ -189,6 +189,7 @@ namespace Microsoft.DotNet.Tools.Compiler
Reporter outputReporter = Reporter.Output;
CommandResult result = _commandFactory.Create($"compile-{compilerName}", new[] { $"@{rsp}" })
.WorkingDirectory(context.ProjectDirectory)
.OnErrorLine(line => HandleCompilerOutputLine(line, context, diagnostics, errorReporter))
.OnOutputLine(line => HandleCompilerOutputLine(line, context, diagnostics, outputReporter))
.Execute();

View file

@ -81,6 +81,13 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
return new AndConstraint<CommandResultAssertions>(this);
}
public AndConstraint<CommandResultAssertions> NotHaveStdErrContaining(string pattern)
{
Execute.Assertion.ForCondition(!_commandResult.StdErr.Contains(pattern))
.FailWith(AppendDiagnosticsTo($"The command error output contained a result it should not have contained: {pattern}{Environment.NewLine}"));
return new AndConstraint<CommandResultAssertions>(this);
}
public AndConstraint<CommandResultAssertions> HaveStdErrMatching(string pattern, RegexOptions options = RegexOptions.None)
{
Execute.Assertion.ForCondition(Regex.Match(_commandResult.StdErr, pattern, options).Success)

View file

@ -217,11 +217,16 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
string cppCompilerFlags="",
bool buildProfile=true,
bool noIncremental=false,
bool noDependencies=false)
bool noDependencies=false,
bool skipLoadProject=false)
: base("dotnet")
{
_projectPath = projectPath;
_project = ProjectReader.GetProject(projectPath);
if (!skipLoadProject)
{
_project = ProjectReader.GetProject(projectPath);
}
_outputDirectory = output;
_buildBasePathDirectory = buildBasePath;

View file

@ -43,6 +43,26 @@ namespace Microsoft.DotNet.Tools.Builder.Tests
.Pass();
}
[Fact]
public void It_builds_projects_with_ruleset_relative_path()
{
var testInstance = TestAssetsManager
.CreateTestInstance("TestRuleSet")
.WithLockFiles();
new BuildCommand(Path.Combine("TestLibraryWithRuleSet", "project.json"), skipLoadProject: true)
.WithWorkingDirectory(testInstance.TestRoot)
.ExecuteWithCapturedOutput()
.Should()
.Pass()
.And
.HaveStdErrContaining("CA1001")
.And
.HaveStdErrContaining("CA2213")
.And
.NotHaveStdErrContaining("CA1018"); // this violation is hidden in the ruleset
}
[Fact]
public void It_builds_projects_with_a_local_project_json_path()
{