From faaf34149b678471cf7cd666c03739e45008b793 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Tue, 17 Nov 2015 11:49:05 +0100 Subject: [PATCH] Try all 4 NuGet APIs for "GetPackageDetails" in parallel - references #1225 --- RELEASE_NOTES.md | 22 +++-------- src/Paket.Core/NuGetV2.fs | 77 ++++++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a27c7a96f3..8d97b8a95f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,24 +1,12 @@ -#### 2.25.8 - 17.11.2015 +#### 2.26.0-alpha001 - 17.11.2015 +* Try all 4 NuGet APIs for "GetPackageDetails" in parallel - https://github.com/fsprojects/Paket/issues/1225 * BUGFIX: Detect AssemblyName from project file name if empty - https://github.com/fsprojects/Paket/issues/1234 - -#### 2.25.7 - 17.11.2015 * BUGFIX: Fixed issue with V3 feeds doing api requests even when the paket.lock is fully specified - https://github.com/fsprojects/Paket/pull/1231 -* USABILITY: Always write nomalized version into lock file to keep the lockfile as stable as possible - -#### 2.25.6 - 16.11.2015 * BUGFIX: Update ProjectFile.GetTargetProfile to work with conditional nodes - https://github.com/fsprojects/Paket/pull/1227 - -#### 2.25.5 - 16.11.2015 -* USABILITY: Sets default resolver strategy for convert from nuget to None - https://github.com/fsprojects/Paket/pull/1228 - -#### 2.25.4 - 16.11.2015 * BUGFIX: Putting .targets import on correct location in project files - https://github.com/fsprojects/Paket/issues/1226 - -#### 2.25.2 - 15.11.2015 -* WORKAROUND: Use file order to work around duplicate files in template definition - https://github.com/fsprojects/Paket/issues/1221 - -#### 2.25.1 - 15.11.2015 -* Always try 3 times to download and extract a package +* USABILITY: Always write nomalized version into lock file to keep the lockfile as stable as possible +* USABILITY: Always try 3 times to download and extract a package +* USABILITY: Sets default resolver strategy for convert from nuget to None - https://github.com/fsprojects/Paket/pull/1228 #### 2.25.0 - 13.11.2015 * Unified cache implementation for V2 and V3 - https://github.com/fsprojects/Paket/pull/1222 diff --git a/src/Paket.Core/NuGetV2.fs b/src/Paket.Core/NuGetV2.fs index a612fc81f6..e92c85acf8 100644 --- a/src/Paket.Core/NuGetV2.fs +++ b/src/Paket.Core/NuGetV2.fs @@ -181,49 +181,75 @@ let parseODataDetails(nugetURL,packageName:PackageName,version,raw) = LicenseUrl = licenseUrl Unlisted = publishDate = Constants.MagicUnlistingDate } - -let getDetailsFromNuGetViaODataFast auth nugetURL (packageName:PackageName) (version:SemVerInfo) = - async { - try +/// Gets package details from NuGet via OData +let getDetailsFromNuGetViaOData auth nugetURL (packageName:PackageName) (version:SemVerInfo) = + let checkODataWithNormalizedVersion = async { + try let url = sprintf "%s/Packages?$filter=Id eq '%O' and NormalizedVersion eq '%s'" nugetURL packageName (version.Normalize()) let! raw = getFromUrl(auth,url,acceptXml) if verbose then tracefn "Response from %s:" url tracefn "" tracefn "%s" raw - return parseODataDetails(nugetURL,packageName,version,raw) - with _ -> + return Some(parseODataDetails(nugetURL,packageName,version,raw)) + with + | _ -> return None } + + let checkODataWithVersion = async { + try let url = sprintf "%s/Packages?$filter=Id eq '%O' and Version eq '%O'" nugetURL packageName version let! raw = getFromUrl(auth,url,acceptXml) if verbose then tracefn "Response from %s:" url tracefn "" tracefn "%s" raw - return parseODataDetails(nugetURL,packageName,version,raw) - } + return Some(parseODataDetails(nugetURL,packageName,version,raw)) + with + | _ -> return None } -/// Gets package details from NuGet via OData -let getDetailsFromNuGetViaOData auth nugetURL (packageName:PackageName) (version:SemVerInfo) = - async { - try - return! getDetailsFromNuGetViaODataFast auth nugetURL packageName version - with _ -> + let checkPackagesWithVersion = async { + try let url = sprintf "%s/Packages(Id='%O',Version='%O')" nugetURL packageName version let! response = safeGetFromUrl(auth,url,acceptXml) - - let! raw = - match response with - | Some(r) -> async { return r } - | None -> - let url = sprintf "%s/odata/Packages(Id='%O',Version='%O')" nugetURL packageName version - getXmlFromUrl(auth,url) - + match response with + | None -> return None + | Some raw -> + if verbose then + tracefn "Response from %s:" url + tracefn "" + tracefn "%s" raw + return Some(parseODataDetails(nugetURL,packageName,version,raw)) + with + | _ -> return None } + + let checkPackagesODataWithVersion = async { + try + let url = sprintf "%s/odata/Packages(Id='%O',Version='%O')" nugetURL packageName version + let! raw = getXmlFromUrl(auth,url) + if verbose then tracefn "Response from %s:" url tracefn "" tracefn "%s" raw - return parseODataDetails(nugetURL,packageName,version,raw) - } + return Some(parseODataDetails(nugetURL,packageName,version,raw)) + with + | _ -> return None } + + + async { + let! result = + [checkODataWithNormalizedVersion + checkODataWithVersion + checkPackagesWithVersion + checkPackagesODataWithVersion ] + |> Async.Choice + + match result with + | Some x -> return x + | None -> + failwithf "Could not get package details for %O %O from %s." packageName version nugetURL + return Unchecked.defaultof<_> // bug in F# 3.0 compiler remove line in F# F 4.0 + } let private loadFromCacheOrODataOrV3 force fileName (auth,nugetURL) package version = async { @@ -258,8 +284,7 @@ let getDetailsFromNuGet force auth nugetURL packageName version = nugetURL packageName version - (fun () -> - getDetailsFromNuGetViaOData auth nugetURL packageName version) + (fun () -> getDetailsFromNuGetViaOData auth nugetURL packageName version) let fixDatesInArchive fileName =