Skip to content
Browse files

Merge commit 'f9e29c8768d62c2cc5d9cd2a447a9b820cd6ec1a' into live

  • Loading branch information...
2 parents b472a62 + f9e29c8 commit 442583f4b65cc8dc2bcd9ae306ea211423ee1fcf @jeffhandley jeffhandley committed May 29, 2012
View
50 Facts/Controllers/ApiControllerFacts.cs
@@ -128,6 +128,51 @@ public void WillCreateAPackageWithTheUserMatchingTheApiKey()
packageSvc.Verify(x => x.CreatePackage(It.IsAny<IPackage>(), matchingUser));
}
+
+ [Fact]
+ public void CreatePackageRefreshesNuGetExeIfCommandLinePackageIsUploaded()
+ {
+ // Arrange
+ var nuGetPackage = new Mock<IPackage>();
+ nuGetPackage.Setup(x => x.Id).Returns("NuGet.CommandLine");
+ nuGetPackage.Setup(x => x.Version).Returns(new SemanticVersion("1.0.42"));
+ var packageSvc = new Mock<IPackageService>();
+ packageSvc.Setup(p => p.CreatePackage(nuGetPackage.Object, It.IsAny<User>())).Returns(new Package { IsLatestStable = true });
+ var userSvc = new Mock<IUserService>();
+ var nugetExeDownloader = new Mock<INuGetExeDownloaderService>(MockBehavior.Strict);
+ nugetExeDownloader.Setup(s => s.UpdateExecutable(nuGetPackage.Object)).Verifiable();
+ var matchingUser = new User();
+ userSvc.Setup(x => x.FindByApiKey(It.IsAny<Guid>())).Returns(matchingUser);
+ var controller = CreateController(userSvc: userSvc, packageSvc: packageSvc, nugetExeDownloader: nugetExeDownloader, packageFromInputStream: nuGetPackage.Object);
+
+ // Act
+ controller.CreatePackagePut(Guid.NewGuid().ToString());
+
+ // Assert
+ nugetExeDownloader.Verify();
+ }
+
+ [Fact]
+ public void CreatePackageDoesNotRefreshNuGetExeIfItIsNotLatestStable()
+ {
+ // Arrange
+ var nuGetPackage = new Mock<IPackage>();
+ nuGetPackage.Setup(x => x.Id).Returns("NuGet.CommandLine");
+ nuGetPackage.Setup(x => x.Version).Returns(new SemanticVersion("2.0.0-alpha"));
+ var packageSvc = new Mock<IPackageService>();
+ packageSvc.Setup(p => p.CreatePackage(nuGetPackage.Object, It.IsAny<User>())).Returns(new Package { IsLatest = true, IsLatestStable = false });
+ var userSvc = new Mock<IUserService>();
+ var nugetExeDownloader = new Mock<INuGetExeDownloaderService>(MockBehavior.Strict);
+ var matchingUser = new User();
+ userSvc.Setup(x => x.FindByApiKey(It.IsAny<Guid>())).Returns(matchingUser);
+ var controller = CreateController(userSvc: userSvc, packageSvc: packageSvc, nugetExeDownloader: nugetExeDownloader, packageFromInputStream: nuGetPackage.Object);
+
+ // Act
+ controller.CreatePackagePut(Guid.NewGuid().ToString());
+
+ // Assert
+ nugetExeDownloader.Verify(s => s.UpdateExecutable(It.IsAny<IPackage>()), Times.Never());
+ }
}
public class TheDeletePackageAction
@@ -492,12 +537,15 @@ private static void AssertStatusCodeResult(ActionResult result, int statusCode,
Mock<IPackageService> packageSvc = null,
Mock<IPackageFileService> fileService = null,
Mock<IUserService> userSvc = null,
+ Mock<INuGetExeDownloaderService> nugetExeDownloader = null,
IPackage packageFromInputStream = null)
{
packageSvc = packageSvc ?? new Mock<IPackageService>();
userSvc = userSvc ?? new Mock<IUserService>();
fileService = fileService ?? new Mock<IPackageFileService>(MockBehavior.Strict);
- var controller = new Mock<ApiController>(packageSvc.Object, fileService.Object, userSvc.Object);
+ nugetExeDownloader = nugetExeDownloader ?? new Mock<INuGetExeDownloaderService>(MockBehavior.Strict);
+
+ var controller = new Mock<ApiController>(packageSvc.Object, fileService.Object, userSvc.Object, nugetExeDownloader.Object);
controller.CallBase = true;
if (packageFromInputStream != null)
controller.Setup(x => x.ReadPackageFromRequest()).Returns(packageFromInputStream);
View
1 Facts/Facts.csproj
@@ -137,6 +137,7 @@
<Compile Include="Services\CloudBlobFileStorageServiceFacts.cs" />
<Compile Include="Services\FileSystemFileStorageServiceFacts.cs" />
<Compile Include="Services\MessageServiceFacts.cs" />
+ <Compile Include="Services\NuGetExeDownloaderServiceFacts.cs" />
<Compile Include="Services\PackageServiceFacts.cs" />
<Compile Include="Services\UploadFileServiceFacts.cs" />
<Compile Include="Services\UsersServiceFacts.cs" />
View
161 Facts/Services/NuGetExeDownloaderServiceFacts.cs
@@ -0,0 +1,161 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Web.Mvc;
+using Moq;
+using NuGet;
+using Xunit;
+
+namespace NuGetGallery.Services
+{
+ public class NuGetExeDownloaderServiceFacts
+ {
+ private static readonly string _exePath = @"x:\NuGetGallery\nuget.exe";
+
+ [Fact]
+ public void CreateNuGetExeDownloadDoesNotExtractFileIfItAlreadyExistsAndIsRecent()
+ {
+ // Arrange
+ var fileSystem = new Mock<IFileSystemService>(MockBehavior.Strict);
+ fileSystem.Setup(s => s.FileExists(_exePath)).Returns(true).Verifiable();
+ fileSystem.Setup(s => s.GetCreationTimeUtc(_exePath))
+ .Returns(DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(60)))
+ .Verifiable();
+
+ // Act
+ var downloaderSvc = GetDownloaderService(fileSystemSvc: fileSystem);
+ var result = downloaderSvc.CreateNuGetExeDownloadActionnResult();
+
+ // Assert
+ fileSystem.Verify();
+ AssertActionResult(result);
+ }
+
+ [Fact]
+ public void CreateNuGetExeDownloadExtractsFileIfItDoesNotExist()
+ {
+ // Arrange
+ var fileSystem = new Mock<IFileSystemService>(MockBehavior.Strict);
+ fileSystem.Setup(s => s.FileExists(_exePath)).Returns(false);
+ fileSystem.Setup(s => s.OpenWrite(_exePath)).Returns(Stream.Null);
+
+ var package = new Package { Version = "2.0.0" };
+ var packageService = new Mock<IPackageService>(MockBehavior.Strict);
+ packageService.Setup(s => s.FindPackageByIdAndVersion("NuGet.CommandLine", null, false))
+ .Returns(package)
+ .Verifiable();
+ var packageFileSvc = new Mock<IPackageFileService>(MockBehavior.Strict);
+ packageFileSvc.Setup(s => s.DownloadPackageFile(package))
+ .Returns(CreateCommandLinePackage)
+ .Verifiable();
+
+ // Act
+ var downloaderSvc = GetDownloaderService(packageService, packageFileSvc, fileSystem);
+ var result = downloaderSvc.CreateNuGetExeDownloadActionnResult();
+
+ // Assert
+ packageFileSvc.Verify();
+ packageService.Verify();
+ AssertActionResult(result);
+ }
+
+ [Fact]
+ public void CreateNuGetExeDownloadExtractsFileIfItExistsButIsNotRecent()
+ {
+ // Arrange
+ var fileSystem = new Mock<IFileSystemService>(MockBehavior.Strict);
+ fileSystem.Setup(s => s.FileExists(_exePath)).Returns(true);
+ fileSystem.Setup(s => s.GetCreationTimeUtc(_exePath))
+ .Returns(DateTime.UtcNow.Subtract(TimeSpan.FromHours(32)));
+ fileSystem.Setup(s => s.OpenWrite(_exePath)).Returns(Stream.Null);
+
+ var package = new Package { Version = "2.0.0" };
+ var packageService = new Mock<IPackageService>(MockBehavior.Strict);
+ packageService.Setup(s => s.FindPackageByIdAndVersion("NuGet.CommandLine", null, false))
+ .Returns(package)
+ .Verifiable();
+ var packageFileSvc = new Mock<IPackageFileService>(MockBehavior.Strict);
+ packageFileSvc.Setup(s => s.DownloadPackageFile(package))
+ .Returns(CreateCommandLinePackage)
+ .Verifiable();
+
+ // Act
+ var downloaderSvc = GetDownloaderService(packageService, packageFileSvc, fileSystem);
+ var result = downloaderSvc.CreateNuGetExeDownloadActionnResult();
+
+ // Assert
+ packageFileSvc.Verify();
+ packageService.Verify();
+ AssertActionResult(result);
+ }
+
+ [Fact]
+ public void UpdateExecutableExtractsExeToDisk()
+ {
+ // Arrange
+ var fileSystem = new Mock<IFileSystemService>(MockBehavior.Strict);
+ fileSystem.Setup(s => s.OpenWrite(_exePath)).Returns(Stream.Null);
+
+ var nugetPackage = new Mock<IPackage>();
+ nugetPackage.Setup(s => s.GetFiles()).Returns(new[] { CreateExePackageFile() }.AsQueryable());
+
+ // Act
+ var downloaderSvc = GetDownloaderService(fileSystemSvc: fileSystem);
+ downloaderSvc.UpdateExecutable(nugetPackage.Object);
+
+ // Assert
+ fileSystem.Verify();
+ }
+
+ private static void AssertActionResult(ActionResult result)
+ {
+ Assert.IsType<FilePathResult>(result);
+ var filePathResult = (FilePathResult)result;
+ Assert.Equal(_exePath, filePathResult.FileName);
+ Assert.Equal(@"application/octet-stream", filePathResult.ContentType);
+ Assert.Equal(@"NuGet.exe", filePathResult.FileDownloadName);
+ }
+
+ private static Stream CreateCommandLinePackage()
+ {
+ var packageBuilder = new PackageBuilder
+ {
+ Id = "NuGet.CommandLine",
+ Version = new SemanticVersion("2.0.0"),
+ Description = "Some desc"
+ };
+ packageBuilder.Authors.Add("test");
+ var exeFile = CreateExePackageFile();
+ packageBuilder.Files.Add(exeFile);
+
+ var memoryStream = new MemoryStream();
+ packageBuilder.Save(memoryStream);
+ memoryStream.Seek(0, SeekOrigin.Begin);
+
+ return memoryStream;
+ }
+
+ private static IPackageFile CreateExePackageFile()
+ {
+ var exeFile = new Mock<IPackageFile>();
+ exeFile.Setup(s => s.Path).Returns(@"tools\NuGet.exe");
+ exeFile.Setup(s => s.GetStream()).Returns(Stream.Null);
+ return exeFile.Object;
+ }
+
+ private static NuGetExeDownloaderService GetDownloaderService(
+ Mock<IPackageService> packageSvc = null,
+ Mock<IPackageFileService> packageFileSvc = null,
+ Mock<IFileSystemService> fileSystemSvc = null)
+ {
+ packageSvc = packageSvc ?? new Mock<IPackageService>(MockBehavior.Strict);
+ packageFileSvc = packageFileSvc ?? new Mock<IPackageFileService>(MockBehavior.Strict);
+ fileSystemSvc = fileSystemSvc ?? new Mock<IFileSystemService>(MockBehavior.Strict);
+
+ return new NuGetExeDownloaderService(packageSvc.Object, packageFileSvc.Object, fileSystemSvc.Object)
+ {
+ NuGetExePath = _exePath
+ };
+ }
+ }
+}
View
6 Website/ApiController.generated.cs
@@ -75,6 +75,7 @@ public partial class ApiController {
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNamesClass {
public readonly string GetPackage = "GetPackageApi";
+ public readonly string GetNuGetExe = "GetNuGetExeApi";
public readonly string VerifyPackageKey = "VerifyPackageKeyApi";
public readonly string CreatePackagePut = "PushPackageApi";
public readonly string CreatePackagePost = "PushPackageApi";
@@ -102,6 +103,11 @@ public class T4MVC_ApiController: NuGetGallery.ApiController {
return callInfo;
}
+ public override System.Web.Mvc.ActionResult GetNuGetExe() {
+ var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.GetNuGetExe);
+ return callInfo;
+ }
+
public override System.Web.Mvc.ActionResult VerifyPackageKey(string apiKey, string id, string version) {
var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.VerifyPackageKey);
callInfo.RouteValueDictionary.Add("apiKey", apiKey);
View
4 Website/App_Start/ContainerBindings.cs
@@ -89,6 +89,10 @@ public override void Load()
.To<LuceneIndexingService>()
.InRequestScope();
+ Bind<INuGetExeDownloaderService>()
+ .To<NuGetExeDownloaderService>()
+ .InRequestScope();
+
Lazy<IMailSender> mailSenderThunk = new Lazy<IMailSender>(() =>
{
var settings = Kernel.Get<GallerySetting>();
View
5 Website/App_Start/Routes.cs
@@ -208,6 +208,11 @@ public static void RegisterRoutes(RouteCollection routes)
"api/v2/",
typeof(V2Feed));
+ routes.MapRoute(
+ RouteName.DownloadNuGetExe,
+ "nuget.exe",
+ new { controller = MVC.Api.Name, action = MVC.Api.ActionNames.GetNuGetExe });
+
// Redirected Legacy Routes
routes.Redirect(
View
1 Website/Constants.cs
@@ -10,6 +10,7 @@ public static class Constants
public const int DefaultPasswordResetTokenExpirationHours = 24;
public const int MaxEmailSubjectLength = 255;
public const string PackageContentType = "application/zip";
+ public const string OctetStreamContentType = "application/octet-stream";
public const string NuGetPackageFileExtension = ".nupkg";
public const string PackageFileDownloadUriTemplate = "packages/{0}/{1}/download";
public const string PackageFileSavePathTemplate = "{0}.{1}{2}";
View
29 Website/Controllers/ApiController.cs
@@ -4,24 +4,31 @@
using System.Linq;
using System.Net;
using System.Web.Mvc;
+using System.Web.UI;
using NuGet;
namespace NuGetGallery
{
public partial class ApiController : Controller
{
+ private const string NuGetCommandLinePackage = "NuGet.CommandLine";
private readonly IPackageService packageSvc;
private readonly IUserService userSvc;
private readonly IPackageFileService packageFileSvc;
+ private readonly INuGetExeDownloaderService nugetExeDownloaderSvc;
- public ApiController(IPackageService packageSvc, IPackageFileService packageFileSvc, IUserService userSvc)
+ public ApiController(IPackageService packageSvc,
+ IPackageFileService packageFileSvc,
+ IUserService userSvc,
+ INuGetExeDownloaderService nugetExeDownloaderSvc)
{
this.packageSvc = packageSvc;
this.packageFileSvc = packageFileSvc;
this.userSvc = userSvc;
+ this.nugetExeDownloaderSvc = nugetExeDownloaderSvc;
}
- [ActionName("GetPackageApi"), HttpGet]
+ [ActionName("GetPackageApi"), HttpGet]
public virtual ActionResult GetPackage(string id, string version)
{
// if the version is null, the user is asking for the latest version. Presumably they don't want pre release versions.
@@ -38,7 +45,17 @@ public virtual ActionResult GetPackage(string id, string version)
if (!string.IsNullOrWhiteSpace(package.ExternalPackageUrl))
return Redirect(package.ExternalPackageUrl);
else
+ {
return packageFileSvc.CreateDownloadPackageActionResult(package);
+ }
+ }
+
+ [ActionName("GetNuGetExeApi"),
+ HttpGet,
+ OutputCache(VaryByParam = "none", Location = OutputCacheLocation.ServerAndClient, Duration = 600)]
+ public virtual ActionResult GetNuGetExe()
+ {
+ return nugetExeDownloaderSvc.CreateNuGetExeDownloadActionnResult();
}
[ActionName("VerifyPackageKeyApi"), HttpGet]
@@ -112,7 +129,13 @@ private ActionResult CreatePackageInternal(string apiKey)
}
}
- packageSvc.CreatePackage(packageToPush, user);
+ var package = packageSvc.CreatePackage(packageToPush, user);
+ if (packageToPush.Id.Equals(NuGetCommandLinePackage, StringComparison.OrdinalIgnoreCase) && package.IsLatestStable)
+ {
+ // If we're pushing a new stable version of NuGet.CommandLine, update the extracted executable.
+ nugetExeDownloaderSvc.UpdateExecutable(packageToPush);
+ }
+
return new HttpStatusCodeResult(201);
}
View
1 Website/RouteNames.cs
@@ -10,6 +10,7 @@ public static class RouteName
public const string Profile = "Profile";
public const string DisplayPackage = "package-route";
public const string DownloadPackage = "DownloadPackage";
+ public const string DownloadNuGetExe = "DownloadNuGetExe";
public const string Home = "Home";
public const string Policies = "Policies";
public const string ListPackages = "ListPackages";
View
8 Website/Services/FileSystemService.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
namespace NuGetGallery
{
@@ -33,5 +34,10 @@ public Stream OpenWrite(string path)
{
return File.OpenWrite(path);
}
+
+ public DateTimeOffset GetCreationTimeUtc(string path)
+ {
+ return File.GetCreationTimeUtc(path);
+ }
}
}
View
4 Website/Services/IFileSystemService.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
namespace NuGetGallery
{
@@ -10,5 +11,6 @@ public interface IFileSystemService
bool FileExists(string path);
Stream OpenRead(string path);
Stream OpenWrite(string path);
+ DateTimeOffset GetCreationTimeUtc(string path);
}
}
View
12 Website/Services/INuGetExeDownloaderService.cs
@@ -0,0 +1,12 @@
+using System.Web.Mvc;
+using NuGet;
+
+namespace NuGetGallery
+{
+ public interface INuGetExeDownloaderService
+ {
+ ActionResult CreateNuGetExeDownloadActionnResult();
+
+ void UpdateExecutable(IPackage package);
+ }
+}
View
16 Website/Services/IPackageFileService.cs
@@ -5,8 +5,24 @@ namespace NuGetGallery
{
public interface IPackageFileService
{
+ /// <summary>
+ /// Creates an ActionResult that allows a third-party client to download the nupkg for the package.
+ /// </summary>
ActionResult CreateDownloadPackageActionResult(Package package);
+
+ /// <summary>
+ /// Deletes the nupkg from the file storage.
+ /// </summary>
void DeletePackageFile(string id, string version);
+
+ /// <summary>
+ /// Saves the contents of the package represented by the stream into the file storage.
+ /// </summary>
void SavePackageFile(Package package, Stream packageFile);
+
+ /// <summary>
+ /// Downloads the package from the file storage and reads it into a Stream.
+ /// </summary>
+ Stream DownloadPackageFile(Package package);
}
}
View
90 Website/Services/NuGetExeDownloaderService.cs
@@ -0,0 +1,90 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using NuGet;
+
+namespace NuGetGallery
+{
+ public class NuGetExeDownloaderService : INuGetExeDownloaderService
+ {
+ private static readonly TimeSpan _exeRefreshInterval = TimeSpan.FromDays(1);
+ private static readonly Lazy<string> _defaultNuGetExePath = new Lazy<string>(() => Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data", "NuGet.exe"));
+ private static readonly object fileLock = new object();
+ private readonly IPackageService packageSvc;
+ private readonly IPackageFileService packageFileSvc;
+ private readonly IFileSystemService fileSystem;
+ private string _nugetExePath;
+
+ public NuGetExeDownloaderService(
+ IPackageService packageSvc,
+ IPackageFileService packageFileSvc,
+ IFileSystemService fileSystem)
+ {
+ this.packageSvc = packageSvc;
+ this.packageFileSvc = packageFileSvc;
+ this.fileSystem = fileSystem;
+ }
+
+ public string NuGetExePath
+ {
+ get { return _nugetExePath ?? _defaultNuGetExePath.Value; }
+ set { _nugetExePath = value; }
+ }
+
+ public ActionResult CreateNuGetExeDownloadActionnResult()
+ {
+ EnsureNuGetExe();
+ var result = new FilePathResult(NuGetExePath, Constants.OctetStreamContentType)
+ {
+ FileDownloadName = "NuGet.exe"
+ };
+ return result;
+ }
+
+ public void UpdateExecutable(IPackage zipPackage)
+ {
+ lock (fileLock)
+ {
+ ExtractNuGetExe(zipPackage);
+ }
+ }
+
+ private void EnsureNuGetExe()
+ {
+ if (fileSystem.FileExists(NuGetExePath) && (DateTime.UtcNow - fileSystem.GetCreationTimeUtc(NuGetExePath)) < _exeRefreshInterval)
+ {
+ // Ensure the file exists and it is recent enough.
+ return;
+ }
+
+ lock (fileLock)
+ {
+ var package = packageSvc.FindPackageByIdAndVersion("NuGet.CommandLine", version: null, allowPrerelease: false);
+ if (package == null)
+ {
+ throw new InvalidOperationException("Unable to find NuGet.CommandLine.");
+ }
+
+ using (var packageStream = packageFileSvc.DownloadPackageFile(package))
+ {
+ var zipPackage = new ZipPackage(packageStream);
+ ExtractNuGetExe(zipPackage);
+ }
+ }
+ }
+
+ private void ExtractNuGetExe(IPackage package)
+ {
+ var executable = package.GetFiles("tools")
+ .First(f => f.Path.Equals(@"tools\NuGet.exe", StringComparison.OrdinalIgnoreCase));
+
+ using (Stream fileStream = fileSystem.OpenWrite(NuGetExePath),
+ packageFileStream = executable.GetStream())
+ {
+ packageFileStream.CopyTo(fileStream);
+ }
+ }
+ }
+}
View
74 Website/Services/PackageFileService.cs
@@ -8,40 +8,24 @@ namespace NuGetGallery
public class PackageFileService : IPackageFileService
{
private readonly IFileStorageService fileStorageSvc;
-
+
public PackageFileService(
IFileStorageService fileStorageSvc)
{
this.fileStorageSvc = fileStorageSvc;
}
- private static string BuildFileName(
- string id,
- string version)
- {
- return String.Format(CultureInfo.InvariantCulture, Constants.PackageFileSavePathTemplate, id, version, Constants.NuGetPackageFileExtension);
- }
-
public ActionResult CreateDownloadPackageActionResult(Package package)
{
- if (package == null)
- throw new ArgumentNullException("package");
- if (package.PackageRegistration == null
- || String.IsNullOrWhiteSpace(package.PackageRegistration.Id)
- || String.IsNullOrWhiteSpace(package.Version))
- throw new ArgumentException("The package is missing required data.", "package");
-
- var fileName = BuildFileName(
- package.PackageRegistration.Id,
- package.Version);
+ var fileName = BuildFileName(package);
return fileStorageSvc.CreateDownloadFileActionResult(
- Constants.PackagesFolderName,
+ Constants.PackagesFolderName,
fileName);
}
public void DeletePackageFile(
- string id,
+ string id,
string version)
{
if (String.IsNullOrWhiteSpace(id))
@@ -52,31 +36,57 @@ public ActionResult CreateDownloadPackageActionResult(Package package)
var fileName = BuildFileName(id, version);
fileStorageSvc.DeleteFile(
- Constants.PackagesFolderName,
+ Constants.PackagesFolderName,
fileName);
}
public void SavePackageFile(
Package package,
Stream packageFile)
{
- if (package == null)
- throw new ArgumentNullException("package");
if (packageFile == null)
throw new ArgumentNullException("packageFile");
- if (package.PackageRegistration == null
- || String.IsNullOrWhiteSpace(package.PackageRegistration.Id)
- || String.IsNullOrWhiteSpace(package.Version))
- throw new ArgumentException("The package is missing required data.", "package");
- var fileName = BuildFileName(
- package.PackageRegistration.Id,
- package.Version);
+ var fileName = BuildFileName(package);
fileStorageSvc.SaveFile(
- Constants.PackagesFolderName,
- fileName,
+ Constants.PackagesFolderName,
+ fileName,
packageFile);
}
+
+
+ public Stream DownloadPackageFile(Package package)
+ {
+ var fileName = BuildFileName(package);
+
+ return fileStorageSvc.GetFile(
+ Constants.PackagesFolderName,
+ fileName);
+ }
+
+ private static string BuildFileName(
+ string id,
+ string version)
+ {
+ return String.Format(CultureInfo.InvariantCulture, Constants.PackageFileSavePathTemplate, id, version, Constants.NuGetPackageFileExtension);
+ }
+
+
+ private static string BuildFileName(Package package)
+ {
+ if (package == null)
+ {
+ throw new ArgumentNullException("package");
+ }
+ if (package.PackageRegistration == null
+ || String.IsNullOrWhiteSpace(package.PackageRegistration.Id)
+ || String.IsNullOrWhiteSpace(package.Version))
+ {
+ throw new ArgumentException("The package is missing required data.", "package");
+ }
+
+ return BuildFileName(package.PackageRegistration.Id, package.Version);
+ }
}
}
View
2 Website/Website.csproj
@@ -345,8 +345,10 @@
<Compile Include="Services\ICloudBlobContainer.cs" />
<Compile Include="Services\IFileStorageService.cs" />
<Compile Include="Services\IIndexingService.cs" />
+ <Compile Include="Services\INuGetExeDownloaderService.cs" />
<Compile Include="Services\ISearchService.cs" />
<Compile Include="Services\IUploadFileService.cs" />
+ <Compile Include="Services\NuGetExeDownloaderService.cs" />
<Compile Include="Services\PackageFileService.cs" />
<Compile Include="RequireRemoteHttpsAttribute.cs" />
<Compile Include="Services\PackageSearchResults.cs" />

0 comments on commit 442583f

Please sign in to comment.
Something went wrong with that request. Please try again.