Merge pull request #2387 from dotnet/brthor/race

fix the race condition when generating deps.json, and add some covera…
This commit is contained in:
Bryan Thornbury 2016-04-11 14:16:09 -07:00
commit 74a42de245
2 changed files with 84 additions and 18 deletions

View file

@ -190,38 +190,68 @@ namespace Microsoft.DotNet.Cli.Utils
depsPathRoot,
toolLibrary.Name + FileNameSuffixes.DepsJson);
EnsureToolJsonDepsFileExists(toolLibrary, toolLockFile, depsJsonPath);
EnsureToolJsonDepsFileExists(toolLockFile, depsJsonPath);
return depsJsonPath;
}
private void EnsureToolJsonDepsFileExists(
LibraryRange toolLibrary,
LockFile toolLockFile,
string depsPath)
{
if (!File.Exists(depsPath))
{
var projectContext = new ProjectContextBuilder()
.WithLockFile(toolLockFile)
.WithTargetFramework(s_toolPackageFramework.ToString())
.Build();
GenerateDepsJsonFile(toolLockFile, depsPath);
}
}
var exporter = projectContext.CreateExporter(Constants.DefaultConfiguration);
// Need to unit test this, so public
public void GenerateDepsJsonFile(
LockFile toolLockFile,
string depsPath)
{
Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}");
var dependencyContext = new DependencyContextBuilder()
.Build(null,
null,
exporter.GetAllExports(),
true,
s_toolPackageFramework,
string.Empty);
var projectContext = new ProjectContextBuilder()
.WithLockFile(toolLockFile)
.WithTargetFramework(s_toolPackageFramework.ToString())
.Build();
using (var fileStream = File.Create(depsPath))
var exporter = projectContext.CreateExporter(Constants.DefaultConfiguration);
var dependencyContext = new DependencyContextBuilder()
.Build(null,
null,
exporter.GetAllExports(),
true,
s_toolPackageFramework,
string.Empty);
var tempDepsFile = Path.GetTempFileName();
using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write))
{
var dependencyContextWriter = new DependencyContextWriter();
dependencyContextWriter.Write(dependencyContext, fileStream);
}
try
{
File.Copy(tempDepsFile, depsPath);
}
catch (Exception e)
{
Reporter.Verbose.WriteLine($"unable to generate deps.json, it may have been already generated: {e.Message}");
}
finally
{
try
{
var dependencyContextWriter = new DependencyContextWriter();
dependencyContextWriter.Write(dependencyContext, fileStream);
File.Delete(tempDepsFile);
}
catch (Exception e2)
{
Reporter.Verbose.WriteLine($"unable to delete temporary deps.json file: {e2.Message}");
}
}
}

View file

@ -18,6 +18,11 @@ using FluentAssertions;
using NuGet.Frameworks;
using NuGet.Versioning;
using NuGet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.ProjectModel.Compilation;
using NuGet.ProjectModel;
using LockFile = Microsoft.DotNet.ProjectModel.Graph.LockFile;
namespace Microsoft.DotNet.Cli.Utils.Tests
{
@ -184,6 +189,37 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
depsJsonFile.Should().NotBeNull();
}
[Fact]
public void Generate_deps_json_method_doesnt_overwrite_when_deps_file_already_exists()
{
var context = ProjectContext.Create(Path.Combine(s_liveProjectDirectory, "project.json"), s_toolPackageFramework);
var nugetPackagesRoot = context.PackagesDirectory;
var toolPathCalculator = new ToolPathCalculator(nugetPackagesRoot);
var lockFilePath = toolPathCalculator.GetLockFilePath(
"dotnet-portable",
new NuGetVersion("1.0.0"),
s_toolPackageFramework);
var lockFile = LockFileReader.Read(lockFilePath, designTime: false);
var depsJsonFile = Path.Combine(
Path.GetDirectoryName(lockFilePath),
"dotnet-portable.deps.json");
if (File.Exists(depsJsonFile))
{
File.Delete(depsJsonFile);
}
File.WriteAllText(depsJsonFile, "temp");
var projectToolsCommandResolver = SetupProjectToolsCommandResolver();
projectToolsCommandResolver.GenerateDepsJsonFile(lockFile, depsJsonFile);
File.ReadAllText(depsJsonFile).Should().Be("temp");
}
private ProjectToolsCommandResolver SetupProjectToolsCommandResolver(
IPackagedCommandSpecFactory packagedCommandSpecFactory = null)
{