Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The restore command should not write any assets itself, everything should be written when the RestoreResult is committed #3261

Merged
merged 5 commits into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 58 additions & 69 deletions src/NuGet.Core/Microsoft.Build.NuGetSdkResolver/RestoreRunnerEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,87 +44,76 @@ public static Task<IReadOnlyList<RestoreResultPair>> RunWithoutCommit(LibraryIde
IgnoreFailedSources = true,
})
{
// Create a unique temporary directory for the project, use the utility method because the temp folder on linux is machine wide.
var projectDirectoryPath = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N"));
DirectoryUtility.CreateSharedDirectory(projectDirectoryPath);
var projectDirectory = new DirectoryInfo(projectDirectoryPath);
var projectDirectory = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N"));

try
{
var projectName = Guid.NewGuid().ToString("N");
var projectName = Guid.NewGuid().ToString("N");

var projectFullPath = Path.Combine(projectDirectory.FullName, $"{projectName}.proj");
var projectFullPath = Path.Combine(projectDirectory, $"{projectName}.proj");

// The package spec details what packages to restore
var packageSpec = new PackageSpec(TargetFrameworks.Select(i => new TargetFrameworkInformation
{
FrameworkName = i,
}).ToList())
// The package spec details what packages to restore
var packageSpec = new PackageSpec(TargetFrameworks.Select(i => new TargetFrameworkInformation
{
FrameworkName = i,
}).ToList())
{
Dependencies = new List<LibraryDependency>
{
Dependencies = new List<LibraryDependency>
{
new LibraryDependency
{
LibraryRange = new LibraryRange(
libraryIdentity.Name,
new VersionRange(
minVersion: libraryIdentity.Version,
includeMinVersion: true,
maxVersion: libraryIdentity.Version,
includeMaxVersion: true),
LibraryDependencyTarget.Package),
SuppressParent = LibraryIncludeFlags.All,
AutoReferenced = true,
IncludeType = LibraryIncludeFlags.None,
Type = LibraryDependencyType.Build
}
},
RestoreMetadata = new ProjectRestoreMetadata
new LibraryDependency
{
ProjectPath = projectFullPath,
ProjectName = projectName,
ProjectStyle = ProjectStyle.PackageReference,
ProjectUniqueName = projectFullPath,
OutputPath = projectDirectory.FullName,
OriginalTargetFrameworks = TargetFrameworks.Select(i => i.ToString()).ToList(),
ConfigFilePaths = settings.GetConfigFilePaths(),
PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings),
Sources = SettingsUtility.GetEnabledSources(settings).ToList(),
FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
},
FilePath = projectFullPath,
Name = projectName,
};

var dependencyGraphSpec = new DependencyGraphSpec();
LibraryRange = new LibraryRange(
libraryIdentity.Name,
new VersionRange(
minVersion: libraryIdentity.Version,
includeMinVersion: true,
maxVersion: libraryIdentity.Version,
includeMaxVersion: true),
LibraryDependencyTarget.Package),
SuppressParent = LibraryIncludeFlags.All,
AutoReferenced = true,
IncludeType = LibraryIncludeFlags.None,
Type = LibraryDependencyType.Build
}
},
RestoreMetadata = new ProjectRestoreMetadata
{
ProjectPath = projectFullPath,
ProjectName = projectName,
ProjectStyle = ProjectStyle.PackageReference,
ProjectUniqueName = projectFullPath,
OutputPath = projectDirectory,
OriginalTargetFrameworks = TargetFrameworks.Select(i => i.ToString()).ToList(),
ConfigFilePaths = settings.GetConfigFilePaths(),
PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings),
Sources = SettingsUtility.GetEnabledSources(settings).ToList(),
FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
},
FilePath = projectFullPath,
Name = projectName,
};

dependencyGraphSpec.AddProject(packageSpec);
var dependencyGraphSpec = new DependencyGraphSpec();

dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);
dependencyGraphSpec.AddProject(packageSpec);

IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);
dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);

var restoreArgs = new RestoreArgs
{
AllowNoOp = false,
CacheContext = sourceCacheContext,
#pragma warning disable CS0618 // Type or member is obsolete
CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)),
#pragma warning restore CS0618 // Type or member is obsolete
Log = logger,
};
IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

// Create requests from the arguments
var requests = requestProvider.CreateRequests(restoreArgs).Result;
var restoreArgs = new RestoreArgs
{
AllowNoOp = false,
CacheContext = sourceCacheContext,
#pragma warning disable CS0618 // Type or member is obsolete
CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)),
#pragma warning restore CS0618 // Type or member is obsolete
Log = logger,
};

// Restore the package without generating extra files
return RestoreRunner.RunWithoutCommit(requests, restoreArgs);
// Create requests from the arguments
var requests = requestProvider.CreateRequests(restoreArgs).Result;

}
finally
{
LocalResourceUtils.DeleteDirectoryTree(projectDirectory.FullName, new List<string>());
nkolev92 marked this conversation as resolved.
Show resolved Hide resolved
}
// Restore the package without generating extra files
return RestoreRunner.RunWithoutCommit(requests, restoreArgs);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class NoOpRestoreResult : RestoreResult
public NoOpRestoreResult(bool success, string lockFilePath, Lazy<LockFile> lockFileLazy, CacheFile cacheFile, string cacheFilePath, ProjectStyle projectStyle, TimeSpan elapsedTime) :
base(success : success, restoreGraphs : null, compatibilityCheckResults : new List<CompatibilityCheckResult>() ,
msbuildFiles : null, lockFile : null, previousLockFile : null, lockFilePath: lockFilePath,
cacheFile: cacheFile, cacheFilePath: cacheFilePath, packagesLockFilePath:null, packagesLockFile:null, projectStyle: projectStyle, elapsedTime: elapsedTime)
cacheFile: cacheFile, cacheFilePath: cacheFilePath, packagesLockFilePath:null, packagesLockFile:null, dependencyGraphSpecFilePath: null, dependencyGraphSpec: null, projectStyle: projectStyle, elapsedTime: elapsedTime)
{
_lockFileLazy = lockFileLazy ?? throw new ArgumentNullException(nameof(lockFileLazy));
}
Expand Down
13 changes: 6 additions & 7 deletions src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ public async Task<RestoreResult> ExecuteAsync(CancellationToken token)
packagesLockFilePath: null,
packagesLockFile: null,
projectStyle: _request.ProjectStyle,
dependencyGraphSpecFilePath: NoOpRestoreUtilities.GetPersistedDGSpecFilePath(_request),
dependencyGraphSpec: _request.DependencyGraphSpec,
elapsedTime: restoreTime.Elapsed);
}

Expand Down Expand Up @@ -234,6 +236,8 @@ public async Task<RestoreResult> ExecuteAsync(CancellationToken token)
cacheFilePath: _request.Project.RestoreMetadata.CacheFilePath,
packagesLockFilePath: packagesLockFilePath,
packagesLockFile: packagesLockFile,
dependencyGraphSpecFilePath: NoOpRestoreUtilities.GetPersistedDGSpecFilePath(_request),
dependencyGraphSpec: _request.DependencyGraphSpec,
projectStyle: _request.ProjectStyle,
elapsedTime: restoreTime.Elapsed);
}
Expand Down Expand Up @@ -391,6 +395,8 @@ public async Task<RestoreResult> ExecuteAsync(CancellationToken token)
cacheFilePath,
packagesLockFilePath,
packagesLockFile,
dependencyGraphSpecFilePath: NoOpRestoreUtilities.GetPersistedDGSpecFilePath(_request),
dependencyGraphSpec: _request.DependencyGraphSpec,
_request.ProjectStyle,
restoreTime.Elapsed);
}
Expand Down Expand Up @@ -602,13 +608,6 @@ private KeyValuePair<CacheFile, bool> EvaluateCacheFile()

}

// We only persist the dg spec file if it nooped or the dg spec does not exist.
var dgPath = NoOpRestoreUtilities.GetPersistedDGSpecFilePath(_request);
if (dgPath != null && (!noOp || !File.Exists(dgPath)))
{
NoOpRestoreUtilities.PersistDGSpecFile(noOpDgSpec, dgPath, _logger);
}

// DotnetCliTool restores are special because the the assets file location is not known until after the restore itself. So we just clean up.
if (_request.ProjectStyle == ProjectStyle.DotnetCliTool)
{
Expand Down
42 changes: 34 additions & 8 deletions src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ public class RestoreResult : IRestoreResult
/// <summary>
/// New Packages lock file path
/// </summary>
private string NewPackagesLockFilePath { get; }
private readonly string _newPackagesLockFilePath;

/// <summary>
/// NuGet lock file which is either generated or updated to lock down NuGet packages version
/// </summary>
private PackagesLockFile NewPackagesLockFile { get; }
private readonly PackagesLockFile _newPackagesLockFile;


private readonly string _dependencyGraphSpecFilePath;

private readonly DependencyGraphSpec _dependencyGraphSpec;

public RestoreResult(
bool success,
Expand All @@ -88,6 +93,8 @@ public RestoreResult(
string cacheFilePath,
string packagesLockFilePath,
PackagesLockFile packagesLockFile,
string dependencyGraphSpecFilePath,
DependencyGraphSpec dependencyGraphSpec,
ProjectStyle projectStyle,
TimeSpan elapsedTime)
{
Expand All @@ -100,8 +107,10 @@ public RestoreResult(
PreviousLockFile = previousLockFile;
CacheFile = cacheFile;
CacheFilePath = cacheFilePath;
NewPackagesLockFilePath = packagesLockFilePath;
NewPackagesLockFile = packagesLockFile;
_newPackagesLockFilePath = packagesLockFilePath;
_newPackagesLockFile = packagesLockFile;
_dependencyGraphSpecFilePath = dependencyGraphSpecFilePath;
_dependencyGraphSpec = dependencyGraphSpec;
ProjectStyle = projectStyle;
ElapsedTime = elapsedTime;
}
Expand Down Expand Up @@ -160,6 +169,11 @@ await CommitCacheFileAsync(
await CommitLockFileAsync(
log: log,
toolCommit: isTool);

// Commit the dg spec file to disk
await CommitDgSpecFileAsync(
log: log,
toolCommit: isTool);
}

private async Task CommitAssetsFileAsync(
Expand Down Expand Up @@ -251,15 +265,27 @@ await FileUtility.ReplaceWithLock(
private async Task CommitLockFileAsync(ILogger log, bool toolCommit)
{
// write packages lock file if it's not tool commit
if (!toolCommit && NewPackagesLockFile != null && !string.IsNullOrEmpty(NewPackagesLockFilePath))
if (!toolCommit && _newPackagesLockFile != null && !string.IsNullOrEmpty(_newPackagesLockFilePath))
{
log.LogInformation(string.Format(CultureInfo.CurrentCulture,
Strings.Log_WritingPackagesLockFile,
NewPackagesLockFilePath));
_newPackagesLockFilePath));

await FileUtility.ReplaceWithLock(
(outputPath) => PackagesLockFileFormat.Write(outputPath, _newPackagesLockFile),
_newPackagesLockFilePath);
}
}

private async Task CommitDgSpecFileAsync(ILogger log, bool toolCommit)
{
if (!toolCommit && _dependencyGraphSpecFilePath != null && _dependencyGraphSpec != null)
{
log.LogVerbose($"Persisting dg to {_dependencyGraphSpecFilePath}");

await FileUtility.ReplaceWithLock(
(outputPath) => PackagesLockFileFormat.Write(outputPath, NewPackagesLockFile),
NewPackagesLockFilePath);
(outputPath) => _dependencyGraphSpec.Save(outputPath),
_dependencyGraphSpecFilePath);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
using NuGet.Common;
using NuGet.LibraryModel;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
Expand Down Expand Up @@ -225,20 +223,6 @@ internal static DependencyGraphSpec GetNoOpDgSpec(RestoreRequest request)
return dgSpec;
}

/// <summary>
/// Persists the dg file for the given restore request.
/// This does not do a dirty check!
/// </summary>
/// <param name="spec">spec</param>
/// <param name="dgPath">the dg path</param>
/// <param name="log">logger</param>
internal static void PersistDGSpecFile(DependencyGraphSpec spec, string dgPath, ILogger log)
{
Directory.CreateDirectory(Path.GetDirectoryName(dgPath));
log.LogVerbose($"Persisting no-op dg to {dgPath}");
spec.Save(dgPath);
}

/// <summary>
/// Gets the path for dgpsec.json.
/// The project style that support dgpsec.json persistance are
Expand Down
Loading