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

fix 'Value cannot be null' when using TFS nuget feed #3341

Merged
merged 1 commit into from
Aug 25, 2018
Merged
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
114 changes: 62 additions & 52 deletions src/Paket.Core/Dependencies/NuGetV3.fs
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,11 @@ let private getPackageIndexPageRaw (source:NuGetV3Source) (url:string) =
| NotFound -> raise (System.Exception(sprintf "could not get registration data (404) from '%s'" url))
| UnknownError err ->
raise (System.Exception(sprintf "could not get registration data from %s" url, err.SourceException))
| SuccessResponse x -> JsonConvert.DeserializeObject<PackageIndexPage>(x)
| SuccessResponse x ->
let page = JsonConvert.DeserializeObject<PackageIndexPage>(x)
if isNull page.Packages || (page.Count > 0 && page.Packages.Length = 0) then
raise <| exn(sprintf "Failed to parse v3 'catalog:CatalogPage' on url '%s'%s" url (if verbose then sprintf ": \n%s" x else ""))
page
}

let private getPackageIndexPageMemoized =
Expand All @@ -772,57 +776,63 @@ let getPackageIndexPage source (page:PackageIndexPage) = getPackageIndexPageMemo

let getRelevantPage (source:NuGetV3Source) (index:PackageIndex) (version:SemVerInfo) =
async {
let normalizedVersion = SemVer.Parse (version.ToString().ToLowerInvariant())
let pages =
index.Pages
|> Seq.filter (fun p -> SemVer.Parse (p.Lower.ToLowerInvariant()) <= normalizedVersion && normalizedVersion <= SemVer.Parse (p.Upper.ToLowerInvariant()))
|> Seq.toList

let tryFindOnPage (page:PackageIndexPage) = async {
let! page = async {
if page.Count > 0 && (isNull page.Packages || page.Packages.Length = 0) then
return! getPackageIndexPage source page
else return page }
if page.Count > 0 && (isNull page.Packages || page.Packages.Length = 0) then
failwithf "Page '%s' should contain packages!" page.Id

let packages =
page.Packages
// TODO: This might need to be part of SemVer itself?
// This is our favorite package: nlog/5.0.0-beta03-tryoutMutex
|> Seq.filter (fun p -> SemVer.Parse (p.PackageDetails.Version.ToLowerInvariant()) = normalizedVersion)
|> Seq.toList
match packages with
| [ package ] -> return Some package
| [] -> return None
| h :: _ ->
// Can happen in theory when multiple versions differ only in casing...
traceWarnfn "Multiple package versions matched with '%O' on page '%s'" version page.Id
return Some h }
match pages with
| [ page ] ->
let! package = tryFindOnPage page
match package with
| Some package -> return Some package
| _ -> return failwithf "Version '%O' should be part of part of page '%s' but wasn't." version page.Id
| [] ->
return None
| multiple ->
// This can happen theoretically because of ToLower, if someone is really crasy enough to upload a package
// with differently cased build strings and if nuget makes a page split exactly at that point.
let mutable result = None
for page in multiple do
if result.IsNone then
let! package = tryFindOnPage page
match package with
| Some package -> result <- Some package
| None -> ()
match result with
| Some result ->
traceWarnfn "Mulitple pages of V3 index '%s' match with version '%O'" index.Id version
return Some result
| None ->
return failwithf "Mulitple pages of V3 index '%s' match with version '%O'" index.Id version
try
let normalizedVersion = SemVer.Parse (version.ToString().ToLowerInvariant())
let pages =
index.Pages
|> Seq.filter (fun p -> SemVer.Parse (p.Lower.ToLowerInvariant()) <= normalizedVersion && normalizedVersion <= SemVer.Parse (p.Upper.ToLowerInvariant()))
|> Seq.toList

let tryFindOnPage (page:PackageIndexPage) = async {
let! page = async {
if isNull page.Packages || (page.Count > 0 && page.Packages.Length = 0) then
return! getPackageIndexPage source page
else return page }
if isNull page.Packages || (page.Count > 0 && page.Packages.Length = 0) then
failwithf "Page '%s' should contain packages!" page.Id

try
let packages =
page.Packages
// TODO: This might need to be part of SemVer itself?
// This is our favorite package: nlog/5.0.0-beta03-tryoutMutex
|> Seq.filter (fun p -> SemVer.Parse (p.PackageDetails.Version.ToLowerInvariant()) = normalizedVersion)
|> Seq.toList
match packages with
| [ package ] -> return Some package
| [] -> return None
| h :: _ ->
// Can happen in theory when multiple versions differ only in casing...
traceWarnfn "Multiple package versions matched with '%O' on page '%s'" version page.Id
return Some h
with e ->
return raise <| exn (sprintf "Failed to find version on page '%s'" page.Id, e) }
match pages with
| [ page ] ->
let! package = tryFindOnPage page
match package with
| Some package -> return Some package
| _ -> return failwithf "Version '%O' should be part of part of page '%s' but wasn't." version page.Id
| [] ->
return None
| multiple ->
// This can happen theoretically because of ToLower, if someone is really crasy enough to upload a package
// with differently cased build strings and if nuget makes a page split exactly at that point.
let mutable result = None
for page in multiple do
if result.IsNone then
let! package = tryFindOnPage page
match package with
| Some package -> result <- Some package
| None -> ()
match result with
| Some result ->
traceWarnfn "Mulitple pages of V3 index '%s' match with version '%O'" index.Id version
return Some result
| None ->
return failwithf "Mulitple pages of V3 index '%s' match with version '%O'" index.Id version
with e ->
return raise <| exn (sprintf "Failed to find relevant page in '%s'" index.Id, e)
}

let getPackageDetails (source:NuGetV3Source) (packageName:PackageName) (version:SemVerInfo) : Async<ODataSearchResult> =
Expand Down