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 the warning reported in #2440 #2449

Merged
merged 2 commits into from
Jun 20, 2017
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
7 changes: 7 additions & 0 deletions integrationtests/Paket.IntegrationTests/PackSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ open System.Diagnostics
open System.IO.Compression
open Paket.Domain
open Paket
open Paket.NuGetCache

let getDependencies = Paket.NuGet.NuGetPackageCache.getDependencies

Expand Down Expand Up @@ -97,6 +98,7 @@ let ``#1429 pack deps from template``() =
let details =
NuGetLocal.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0")
|> Async.RunSynchronously
|> ODataSearchResult.get

details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data")
details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug2") // it's not packed in same round
Expand All @@ -113,6 +115,7 @@ let ``#1429 pack deps``() =
let details =
NuGetLocal.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0")
|> Async.RunSynchronously
|> ODataSearchResult.get

details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data")
details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "PaketBug2")
Expand All @@ -129,6 +132,7 @@ let ``#1429 pack deps using minimum-from-lock-file``() =
let details =
NuGetLocal.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0")
|> Async.RunSynchronously
|> ODataSearchResult.get

details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data")
let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head
Expand All @@ -145,6 +149,7 @@ let ``#1429 pack deps without minimum-from-lock-file uses dependencies file rang
let details =
NuGetLocal.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0")
|> Async.RunSynchronously
|> ODataSearchResult.get

details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data")
let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head
Expand All @@ -161,6 +166,7 @@ let ``#1429 pack deps without minimum-from-lock-file uses specifc dependencies f
let details =
NuGetLocal.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0")
|> Async.RunSynchronously
|> ODataSearchResult.get

details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data")
let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head
Expand All @@ -177,6 +183,7 @@ let ``#1429 pack deps with minimum-from-lock-file uses specifc dependencies file
let details =
NuGetLocal.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0")
|> Async.RunSynchronously
|> ODataSearchResult.get

details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data")
let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head
Expand Down
5 changes: 4 additions & 1 deletion src/Paket.Core/Common/Async.fs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ module AsyncExtensions =
if t.IsCanceled then
cancel (OperationCanceledException("The underlying task has been cancelled"))
elif t.IsFaulted then
error t.Exception
if t.Exception.InnerExceptions.Count = 1 then
error t.Exception.InnerExceptions.[0]
else
error t.Exception
else success t.Result))
|> ignore
} |> fun a -> Async.Start(a, ct)
Expand Down
47 changes: 35 additions & 12 deletions src/Paket.Core/Common/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ let createWebClient (url,auth:Auth option) =
open System.Diagnostics
open System.Threading
open System.Collections.Generic
open System.Runtime.ExceptionServices

/// [omit]
let downloadFromUrl (auth:Auth option, url : string) (filePath: string) =
Expand Down Expand Up @@ -580,7 +581,7 @@ let getFromUrl (auth:Auth option, url : string, contentType : string) =
}

let getXmlFromUrl (auth:Auth option, url : string) =
async {
async {
try
use client = createWebClient (url,auth)
// mimic the headers sent from nuget client to odata/ endpoints
Expand All @@ -593,17 +594,36 @@ let getXmlFromUrl (auth:Auth option, url : string) =
use _ = Profile.startCategory Profile.Category.NuGetRequest
return! client.DownloadStringTaskAsync (Uri url) |> Async.awaitTaskWithToken (fun () -> failwithf "Uri '%O' failed to respond and cancellation was requested." url)
with
| exn ->
| exn ->
return raise <| Exception(sprintf "Could not retrieve data from '%s'" url, exn)
}


type SafeWebResult<'a> =
| NotFound
| SuccessResponse of 'a
| UnknownError of ExceptionDispatchInfo
module SafeWebResult =
let map f s =
match s with
| SuccessResponse r -> SuccessResponse (f r)
| UnknownError err -> UnknownError err
| NotFound -> NotFound
let asResult s =
match s with
| NotFound ->
let notFound = Exception("Request returned 404")
ExceptionDispatchInfo.Capture notFound
|> FSharp.Core.Result.Error
| UnknownError err -> FSharp.Core.Result.Error err
| SuccessResponse s -> FSharp.Core.Result.Ok s

/// [omit]
let safeGetFromUrl (auth:Auth option, url : string, contentType : string) =
async {
try
async {
try
let uri = Uri url
use client = createWebClient (url,auth)

if notNullOrEmpty contentType then
addAcceptHeader client contentType
#if NETSTANDARD1_6
Expand All @@ -614,12 +634,15 @@ let safeGetFromUrl (auth:Auth option, url : string, contentType : string) =
verbosefn "Starting request to '%O'" uri
use _ = Profile.startCategory Profile.Category.NuGetRequest
let! raw = client.DownloadStringTaskAsync(uri) |> Async.awaitTaskWithToken (fun () -> failwithf "Uri '%O' failed to respond and cancellation was requested." uri)
return FSharp.Core.Result.Ok raw
with e ->
if verbose then
Logging.verbosefn "Error while retrieving '%s': %O" url e
let cap = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture e
return FSharp.Core.Result.Error cap
return SuccessResponse raw
with
| :? WebException as w ->
match w.Response with
| :? HttpWebResponse as wr when wr.StatusCode = HttpStatusCode.NotFound -> return NotFound
| _ ->
if verbose then
Logging.verbosefn "Error while retrieving '%s': %O" url w
return UnknownError (ExceptionDispatchInfo.Capture w)
}

let mutable autoAnswer = None
Expand Down
97 changes: 40 additions & 57 deletions src/Paket.Core/Dependencies/NuGet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ open System.Net
open System.Runtime.ExceptionServices
open System.Text
open FSharp.Polyfill
open Paket.NuGetCache


let DownloadLicense(root,force,packageName:PackageName,version:SemVerInfo,licenseUrl,targetFileName) =
Expand Down Expand Up @@ -120,93 +121,82 @@ let tryNuGetV3 (auth, nugetV3Url, package:PackageName) =

let rec private getPackageDetails alternativeProjectRoot root force (sources:PackageSource list) packageName (version:SemVerInfo) : Async<PackageResolver.PackageDetails> =
async {
let tryV2 source (nugetSource:NugetSource) force = async {
let! result =
NuGetV2.getDetailsFromNuGet
force
(nugetSource.Authentication |> Option.map toBasicAuth)
nugetSource.Url
packageName
version
return Choice1Of2(source,result) }

let tryV3 source nugetSource force = async {
let tryV2 (nugetSource:NugetSource) force =
NuGetV2.getDetailsFromNuGet
force
(nugetSource.Authentication |> Option.map toBasicAuth)
nugetSource.Url
packageName
version

let tryV3 (nugetSource:NugetV3Source) force =
if nugetSource.Url.Contains("myget.org") || nugetSource.Url.Contains("nuget.org") || nugetSource.Url.Contains("visualstudio.com") || nugetSource.Url.Contains("/nuget/v3/") then
match NuGetV3.calculateNuGet2Path nugetSource.Url with
| Some url ->
let! result =
NuGetV2.getDetailsFromNuGet
force
(nugetSource.Authentication |> Option.map toBasicAuth)
url
packageName
version
return Choice1Of2(source,result)
NuGetV2.getDetailsFromNuGet
force
(nugetSource.Authentication |> Option.map toBasicAuth)
url
packageName
version
| _ ->
let! result = NuGetV3.GetPackageDetails force nugetSource packageName version
return Choice1Of2(source,result)
NuGetV3.GetPackageDetails force nugetSource packageName version
else
let! result = NuGetV3.GetPackageDetails force nugetSource packageName version
return Choice1Of2(source,result) }
NuGetV3.GetPackageDetails force nugetSource packageName version

let getPackageDetails force =
// helper to work through the list sequentially
let rec trySelectFirst errors workLeft =
let rec trySelectFirst workLeft =
async {
match workLeft with
| work :: rest ->
| (source, work) :: rest ->
let! r = work
match r with
| Choice1Of2 result -> return Choice1Of2 result
| Choice2Of2 error -> return! trySelectFirst (error::errors) rest
| [] -> return Choice2Of2 errors
| ODataSearchResult.Match result -> return Some (source, result)
| ODataSearchResult.EmptyResult -> return! trySelectFirst rest
| [] -> return None
}
sources
|> List.sortBy (fun source ->
match source with // put local caches to the end
| LocalNuGet(_,Some _) -> true
| _ -> false)
|> List.map (fun source -> async {
|> List.map (fun source -> source, async {
try
match source with
| NuGetV2 nugetSource ->
return! tryV2 source nugetSource force
return! tryV2 nugetSource force
| NuGetV3 nugetSource when NuGetV2.urlSimilarToTfsOrVsts nugetSource.Url ->
match NuGetV3.calculateNuGet2Path nugetSource.Url with
| Some url ->
let nugetSource : NugetSource =
{ Url = url
Authentication = nugetSource.Authentication }
return! tryV2 source nugetSource force
return! tryV2 nugetSource force
| _ ->
return! tryV3 source nugetSource force
return! tryV3 nugetSource force
| NuGetV3 nugetSource ->
try
return! tryV3 source nugetSource force
return! tryV3 nugetSource force
with
| exn ->
match NuGetV3.calculateNuGet2Path nugetSource.Url with
| Some url ->
let nugetSource : NugetSource =
{ Url = url
Authentication = nugetSource.Authentication }
return! tryV2 source nugetSource force
return! tryV2 nugetSource force
| _ ->
raise exn
return! tryV3 source nugetSource force

| LocalNuGet(path,Some _) ->
let! result = NuGetLocal.getDetailsFromLocalNuGetPackage true alternativeProjectRoot root path packageName version
return Choice1Of2(source,result)
| LocalNuGet(path,None) ->
let! result = NuGetLocal.getDetailsFromLocalNuGetPackage false alternativeProjectRoot root path packageName version
return Choice1Of2(source,result)
return! tryV3 nugetSource force

| LocalNuGet(path,hasCache) ->
return! NuGetLocal.getDetailsFromLocalNuGetPackage hasCache.IsSome alternativeProjectRoot root path packageName version
with e ->
if verbose then
verbosefn "Source '%O' exception: %O" source e
let capture = ExceptionDispatchInfo.Capture e
return Choice2Of2 capture })
|> trySelectFirst []
traceWarnfn "Source '%O' exception: %O" source e
//let capture = ExceptionDispatchInfo.Capture e
return EmptyResult })
|> trySelectFirst

let! maybePackageDetails = getPackageDetails force
let! source,nugetObject =
Expand All @@ -219,17 +209,10 @@ let rec private getPackageDetails alternativeProjectRoot root force (sources:Pac
failwithf "Couldn't get package details for package %O %O, because no sources were specified." packageName version
| sources ->
failwithf "Couldn't get package details for package %O %O on any of %A." packageName version sources

match maybePackageDetails with
| Choice2Of2 ([]) -> return fallback()
| Choice2Of2 (h::restError) ->
for error in restError do
if not verbose then
// Otherwise the error was already mentioned above
traceWarnfn "Ignoring: %s" error.SourceException.Message
h.Throw()
return fallback()
| Choice1Of2 packageDetails -> return packageDetails
| None -> return fallback()
| Some packageDetails -> return packageDetails
}

let encodeURL (url:string) =
Expand Down
32 changes: 23 additions & 9 deletions src/Paket.Core/Dependencies/NuGetCache.fs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type NuGetResponseGetVersions =
| SuccessVersionResponse _ -> true
| ProtocolNotCached -> false
| FailedVersionRequest _ -> false
type NuGetResponseGetVersionsSimple = FSharp.Core.Result<NuGetResponseGetVersionsSuccess, ExceptionDispatchInfo>
type NuGetResponseGetVersionsSimple = SafeWebResult<NuGetResponseGetVersionsSuccess>
type NuGetRequestGetVersions =
{ DoRequest : unit -> Async<NuGetResponseGetVersions>
Url : string }
Expand All @@ -61,8 +61,9 @@ type NuGetRequestGetVersions =
let! res = f()
return
match res with
| FSharp.Core.Result.Ok r -> SuccessVersionResponse r
| FSharp.Core.Result.Error err -> FailedVersionRequest { Url = url; Error = err }
| SuccessResponse r -> SuccessVersionResponse r
| NotFound -> SuccessVersionResponse [||]
| UnknownError err -> FailedVersionRequest { Url = url; Error = err }
})
static member run (r:NuGetRequestGetVersions) : Async<NuGetResponseGetVersions> =
async {
Expand Down Expand Up @@ -117,7 +118,7 @@ type NuGetPackageCache =
Version: string
CacheVersion: string }

static member CurrentCacheVersion = "5.0"
static member CurrentCacheVersion = "5.1"

// TODO: is there a better way? for now we use static member because that works with type abbreviations...
//module NuGetPackageCache =
Expand Down Expand Up @@ -156,13 +157,27 @@ let getCacheFiles cacheVersion nugetURL (packageName:PackageName) (version:SemVe
|> Seq.filter (fun p -> Path.GetFileName p <> packageUrl)
|> Seq.toList
FileInfo(newFile), oldFiles
let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemVerInfo) (get : unit -> NuGetPackageCache Async) : NuGetPackageCache Async =

type ODataSearchResult =
| EmptyResult
| Match of NuGetPackageCache
module ODataSearchResult =
let get x =
match x with
| EmptyResult -> failwithf "Cannot call get on 'EmptyResult'"
| Match r -> r
let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemVerInfo) (get : unit -> ODataSearchResult Async) : ODataSearchResult Async =
let cacheFile, oldFiles = getCacheFiles NuGetPackageCache.CurrentCacheVersion nugetURL packageName version
oldFiles |> Seq.iter (fun f -> File.Delete f)
let get() =
let get() =
async {
let! result = get()
File.WriteAllText(cacheFile.FullName,JsonConvert.SerializeObject(result))
match result with
| ODataSearchResult.Match result ->
File.WriteAllText(cacheFile.FullName,JsonConvert.SerializeObject(result))
| _ ->
// TODO: Should we cache 404? Probably not.
()
return result
}
async {
Expand All @@ -171,7 +186,6 @@ let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemV
let cacheResult =
try
let cachedObject = JsonConvert.DeserializeObject<NuGetPackageCache> json

if (PackageName cachedObject.PackageName <> packageName) ||
(cachedObject.Version <> version.Normalize())
then
Expand All @@ -189,7 +203,7 @@ let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemV
traceWarnfn "Error while loading cache: %s" exn.Message
None
match cacheResult with
| Some res -> return res
| Some res -> return ODataSearchResult.Match res
| None -> return! get()
else
return! get()
Expand Down
Loading