Skip to content
New issue

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

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

Already on GitHub? # to your account

fix: file locking when running msbuild task #23

Merged
merged 1 commit into from
Jun 16, 2019
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
29 changes: 19 additions & 10 deletions src/Pharmacist.Core/NuGet/NuGetPackageHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ static NuGetPackageHelper()
_globalPackagesPath = SettingsUtility.GetGlobalPackagesFolder(machineWideSettings.Settings.LastOrDefault() ?? (ISettings)NullSettings.Instance);
}

/// <summary>
/// Gets the directory where the packages will be stored.
/// </summary>
public static string PackageDirectory { get; } = Path.Combine(Path.GetTempPath(), "ReactiveUI.Pharmacist");

/// <summary>
/// Gets the providers for the nuget resources.
/// </summary>
Expand All @@ -72,6 +67,7 @@ static NuGetPackageHelper()
/// <param name="nugetSource">Optional v3 nuget source. Will default to default nuget.org servers.</param>
/// <param name="getDependencies">If we should get the dependencies.</param>
/// <param name="packageFolders">Directories to package folders. Will be lib/build/ref if not defined.</param>
/// <param name="packageDirectory">A directory where to store the files, if null a random location will be used.</param>
/// <param name="token">A cancellation token.</param>
/// <returns>The directory where the NuGet packages are unzipped to. Also the files contained within the requested package only.</returns>
public static async Task<IReadOnlyCollection<(string folder, IReadOnlyCollection<string> files)>> DownloadPackageFilesAndFolder(
Expand All @@ -80,6 +76,7 @@ static NuGetPackageHelper()
PackageSource nugetSource = null,
bool getDependencies = true,
IReadOnlyCollection<string> packageFolders = null,
string packageDirectory = null,
CancellationToken token = default)
{
// If the user hasn't selected a default framework to extract, select .NET Standard 2.0
Expand All @@ -90,7 +87,7 @@ static NuGetPackageHelper()

var packages = await Task.WhenAll(libraryIdentities.Select(x => GetBestMatch(x, sourceRepository, token))).ConfigureAwait(false);

return await DownloadPackageFilesAndFolder(packages, frameworks, sourceRepository, getDependencies, packageFolders, token).ConfigureAwait(false);
return await DownloadPackageFilesAndFolder(packages, frameworks, sourceRepository, getDependencies, packageFolders, packageDirectory, token).ConfigureAwait(false);
}

/// <summary>
Expand All @@ -101,6 +98,7 @@ static NuGetPackageHelper()
/// <param name="nugetSource">Optional v3 nuget source. Will default to default nuget.org servers.</param>
/// <param name="getDependencies">If we should get the dependencies.</param>
/// <param name="packageFolders">Directories to package folders. Will be lib/build/ref if not defined.</param>
/// <param name="packageDirectory">A directory where to store the files, if null a random location will be used.</param>
/// <param name="token">A cancellation token.</param>
/// <returns>The directory where the NuGet packages are unzipped to. Also the files contained within the requested package only.</returns>
public static Task<IReadOnlyCollection<(string folder, IReadOnlyCollection<string> files)>> DownloadPackageFilesAndFolder(
Expand All @@ -109,6 +107,7 @@ static NuGetPackageHelper()
PackageSource nugetSource = null,
bool getDependencies = true,
IReadOnlyCollection<string> packageFolders = null,
string packageDirectory = null,
CancellationToken token = default)
{
// If the user hasn't selected a default framework to extract, select .NET Standard 2.0
Expand All @@ -117,7 +116,7 @@ static NuGetPackageHelper()
// Use the provided nuget package source, or use nuget.org
var sourceRepository = new SourceRepository(nugetSource ?? new PackageSource(DefaultNuGetSource), Providers);

return DownloadPackageFilesAndFolder(packageIdentities, frameworks, sourceRepository, getDependencies, packageFolders, token);
return DownloadPackageFilesAndFolder(packageIdentities, frameworks, sourceRepository, getDependencies, packageFolders, packageDirectory, token);
}

/// <summary>
Expand Down Expand Up @@ -146,6 +145,7 @@ public static async Task<PackageIdentity> GetBestMatch(LibraryRange identity, So
/// <param name="sourceRepository">Nuget source repository. Will default to default nuget.org servers.</param>
/// <param name="getDependencies">If we should get the dependencies.</param>
/// <param name="packageFolders">Directories to package folders. Will be lib/build/ref if not defined.</param>
/// <param name="packageDirectory">A directory where to store the files, if null a random location will be used.</param>
/// <param name="token">A cancellation token.</param>
/// <returns>The directory where the NuGet packages are unzipped to. Also the files contained within the requested package only.</returns>
private static async Task<IReadOnlyCollection<(string folder, IReadOnlyCollection<string> files)>> DownloadPackageFilesAndFolder(
Expand All @@ -154,11 +154,14 @@ public static async Task<PackageIdentity> GetBestMatch(LibraryRange identity, So
SourceRepository sourceRepository,
bool getDependencies = true,
IReadOnlyCollection<string> packageFolders = null,
string packageDirectory = null,
CancellationToken token = default)
{
var librariesToCopy = await GetPackagesToCopy(packageIdentities, sourceRepository, frameworks.First(), getDependencies, token).ConfigureAwait(false);

return CopyPackageFiles(librariesToCopy, frameworks, packageFolders ?? DefaultFoldersToGrab, token);
packageDirectory = packageDirectory ?? GetRandomPackageDirectory();

return CopyPackageFiles(librariesToCopy, frameworks, packageFolders ?? DefaultFoldersToGrab, packageDirectory, token);
}

private static async Task<IEnumerable<(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, bool includeFilesInOutput)>> GetPackagesToCopy(
Expand Down Expand Up @@ -223,13 +226,13 @@ public static async Task<PackageIdentity> GetBestMatch(LibraryRange identity, So
return packagesToCopy.Select(x => (x.Value.packageIdentity, x.Value.downloadResourceResult, x.Value.includeFilesInOutput));
}

private static IReadOnlyCollection<(string folder, IReadOnlyCollection<string> files)> CopyPackageFiles(IEnumerable<(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, bool includeFilesInOutput)> packagesToProcess, IReadOnlyCollection<NuGetFramework> frameworks, IReadOnlyCollection<string> packageFolders, CancellationToken token)
private static IReadOnlyCollection<(string folder, IReadOnlyCollection<string> files)> CopyPackageFiles(IEnumerable<(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, bool includeFilesInOutput)> packagesToProcess, IReadOnlyCollection<NuGetFramework> frameworks, IReadOnlyCollection<string> packageFolders, string packageDirectory, CancellationToken token)
{
var output = new List<(string folder, IReadOnlyCollection<string> files)>();
foreach (var packageToProcess in packagesToProcess)
{
var (packageIdentity, downloadResourceResults, includeFilesInOutput) = packageToProcess;
var directory = Path.Combine(PackageDirectory, packageIdentity.Id, packageIdentity.Version.ToNormalizedString());
var directory = Path.Combine(packageDirectory, packageIdentity.Id, packageIdentity.Version.ToNormalizedString());

EnsureDirectory(directory);

Expand Down Expand Up @@ -260,6 +263,12 @@ public static async Task<PackageIdentity> GetBestMatch(LibraryRange identity, So
return output;
}

private static string GetRandomPackageDirectory()
{
var packageDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
return packageDirectory;
}

/// <summary>
/// Gets dependency packages that matches our framework (current version or below).
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,15 @@ namespace Pharmacist.Core.NuGet
public class static NuGetPackageHelper
{
public const string DefaultNuGetSource = "https://api.nuget.org/v3/index.json";
public static string PackageDirectory { get; }
public static System.Collections.Generic.List<System.Lazy<NuGet.Protocol.Core.Types.INuGetResourceProvider>> Providers { get; }
[return: System.Runtime.CompilerServices.TupleElementNamesAttribute(new string[] {
"folder",
"files"})]
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.LibraryModel.LibraryRange> libraryIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, System.Threading.CancellationToken token = null) { }
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.LibraryModel.LibraryRange> libraryIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, string packageDirectory = null, System.Threading.CancellationToken token = null) { }
[return: System.Runtime.CompilerServices.TupleElementNamesAttribute(new string[] {
"folder",
"files"})]
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.Packaging.Core.PackageIdentity> packageIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, System.Threading.CancellationToken token = null) { }
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.Packaging.Core.PackageIdentity> packageIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, string packageDirectory = null, System.Threading.CancellationToken token = null) { }
public static System.Threading.Tasks.Task<NuGet.Packaging.Core.PackageIdentity> GetBestMatch(NuGet.LibraryModel.LibraryRange identity, NuGet.Protocol.Core.Types.SourceRepository sourceRepository, System.Threading.CancellationToken token) { }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,15 @@ namespace Pharmacist.Core.NuGet
public class static NuGetPackageHelper
{
public const string DefaultNuGetSource = "https://api.nuget.org/v3/index.json";
public static string PackageDirectory { get; }
public static System.Collections.Generic.List<System.Lazy<NuGet.Protocol.Core.Types.INuGetResourceProvider>> Providers { get; }
[return: System.Runtime.CompilerServices.TupleElementNamesAttribute(new string[] {
"folder",
"files"})]
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.LibraryModel.LibraryRange> libraryIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, System.Threading.CancellationToken token = null) { }
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.LibraryModel.LibraryRange> libraryIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, string packageDirectory = null, System.Threading.CancellationToken token = null) { }
[return: System.Runtime.CompilerServices.TupleElementNamesAttribute(new string[] {
"folder",
"files"})]
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.Packaging.Core.PackageIdentity> packageIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, System.Threading.CancellationToken token = null) { }
public static System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyCollection<System.ValueTuple<string, System.Collections.Generic.IReadOnlyCollection<string>>>> DownloadPackageFilesAndFolder(System.Collections.Generic.IReadOnlyCollection<NuGet.Packaging.Core.PackageIdentity> packageIdentities, System.Collections.Generic.IReadOnlyCollection<NuGet.Frameworks.NuGetFramework> frameworks = null, NuGet.Configuration.PackageSource nugetSource = null, bool getDependencies = True, System.Collections.Generic.IReadOnlyCollection<string> packageFolders = null, string packageDirectory = null, System.Threading.CancellationToken token = null) { }
public static System.Threading.Tasks.Task<NuGet.Packaging.Core.PackageIdentity> GetBestMatch(NuGet.LibraryModel.LibraryRange identity, NuGet.Protocol.Core.Types.SourceRepository sourceRepository, System.Threading.CancellationToken token) { }
}
}
Expand Down
18 changes: 4 additions & 14 deletions src/Pharmacist.Tests/NuGetPackageHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,6 @@ public class NuGetPackageHelperTests
"Tizen.NET.API4" + Path.DirectorySeparatorChar + "4.0.1.14152"
};

/// <summary>
/// Initializes a new instance of the <see cref="NuGetPackageHelperTests"/> class.
/// </summary>
public NuGetPackageHelperTests()
{
if (Directory.Exists(NuGetPackageHelper.PackageDirectory))
{
Directory.Delete(NuGetPackageHelper.PackageDirectory, true);
}
}

/// <summary>
/// Check to make sure that the tizen packages produce the correct files.
/// </summary>
Expand Down Expand Up @@ -157,7 +146,7 @@ public async Task CanGetNuGetProtocolAndDependencies()
var frameworks = new[] { FrameworkConstants.CommonFrameworks.NetStandard20 };

var result = (await NuGetPackageHelper
.DownloadPackageFilesAndFolder(package, frameworks: frameworks)
.DownloadPackageFilesAndFolder(package, frameworks)
.ConfigureAwait(false)).ToList();

result.ShouldNotBeEmpty();
Expand All @@ -168,8 +157,9 @@ private static async Task GetAndCheckTizenPackage()
var package = new[] { new PackageIdentity("Tizen.NET.API4", new NuGetVersion("4.0.1.14152")) };
var frameworks = new[] { FrameworkConstants.CommonFrameworks.NetStandard20 };

var packageDirectory = Path.Combine(Path.GetTempPath(), "Pharmacist.Tests");
var result = (await NuGetPackageHelper
.DownloadPackageFilesAndFolder(package, frameworks: frameworks)
.DownloadPackageFilesAndFolder(package, frameworks, packageDirectory: packageDirectory)
.ConfigureAwait(false)).ToList();

var actualFiles = result.SelectMany(x => x.files).Where(x => x.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase)).ToList();
Expand All @@ -178,7 +168,7 @@ private static async Task GetAndCheckTizenPackage()
Assert.True(actualDirectories.All(Directory.Exists));

var actualFileNames = actualFiles.Select(Path.GetFileName).ToList();
var actualDirectoryNames = actualDirectories.Select(x => x.Replace(NuGetPackageHelper.PackageDirectory + Path.DirectorySeparatorChar, string.Empty)).ToList();
var actualDirectoryNames = actualDirectories.Select(x => x.Replace(packageDirectory + Path.DirectorySeparatorChar, string.Empty)).ToList();
ExpectedTizenFiles.ShouldHaveSameContents(actualFileNames);
ExpectedTizenDirectories.ShouldHaveSameContents(actualDirectoryNames);
}
Expand Down