Skip to content

Dependency manager looks up older tool version of paket #4164

Open

Agent suggestions

Public preview

Description

@aggieben

Description

When I run FSI using the Dependency Manager extension for paket, it resolves a path to paket.exe through an older version of a dotnet CLI tool package.

Repro steps

Please provide the steps required to reproduce the problem

  1. Launch FSI with dotnet fsi --compilertool:"D:\Users\ben\proj\mbrace\MBrace.Core\packages\fsi\FSharp.DependencyManager.Paket\lib\netstandard2.0\"

  2. Evaluate this: #r "packet: nuget FSharp.Data" // or any package name, this is just the one I used.

Expected behavior

The dependency manager resolves to latest available version of the paket cli tool and successfully resolves requested package.

Actual behavior

λ dotnet fsi --compilertool:"D:\Users\ben\proj\mbrace\MBrace.Core\packages\fsi\FSharp.DependencyManager.Paket\lib\netstandard2.0\"

Microsoft (R) F# Interactive version 12.0.4.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> #r "paket: nuget FSharp.Data";;
:paket> using C:\Users\Ben\.nuget\packages\paket\6.0.0-beta2\tools\paket.exe
:paket> Paket version 6.0.0-beta2
:paket> Total time taken: 0 milliseconds
exception while resolving dependencies: System.Exception: Package resolution using 'C:\Users\Ben\.nuget\packages\paket\6.0.0-beta2\tools\paket.exe' failed, see directory 'C:\Users\Ben\AppData\Local\Temp\script-packages\1601146677'.
Paket failed with
-> Error in paket.dependencies line 1
     Could not parse framework 'net6.0'. Try to update or install again or report a paket bug.
   at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1448.Invoke(String message)
   at ReferenceLoading.PaketHandler.ResolveDependenciesForLanguage$cont@168(String targetFramework, String scriptDir, IEnumerable`1 prioritizedSearchPaths, String fileType, String workingDir, FileInfo workingDirSpecFile, String rootDir, FSharpList`1 packageManagerTextLines, String loadScript, Unit unitVar) in D:\code\Paket\src\FSharp.DependencyManager.Paket\ReferenceLoading.PaketHandler.fs:line 253
   at ReferenceLoading.PaketHandler.ResolveDependenciesForLanguage(String fileType, String targetFramework, IEnumerable`1 prioritizedSearchPaths, String scriptDir, String scriptName, IEnumerable`1 packageManagerTextLinesFromScript) in D:\code\Paket\src\FSharp.DependencyManager.Paket\ReferenceLoading.PaketHandler.fs:line 168
   at ReferenceLoading.PaketHandler.ResolveDependencies(String targetFramework, String scriptDir, String scriptName, IEnumerable`1 packageManagerTextLinesFromScript) in D:\code\Paket\src\FSharp.DependencyManager.Paket\ReferenceLoading.PaketHandler.fs:line 272
   at Microsoft.FSharp.DependencyManager.Paket.PaketDependencyManagerProvider.ResolveDependencies(String scriptDir, String mainScriptName, String scriptName, IEnumerable`1 packageManagerTextLines, String targetFramework) in D:\code\Paket\src\FSharp.DependencyManager.Paket\PaketDependencyManager.fs:line 44
>

I have the following installed versions of the paket CLI tool:

λ ls ~/.nuget/packages/paket

        Directory: C:\Users\Ben\.nuget\packages\paket


Mode                LastWriteTime       FileSize Name
----                -------------       -------- ----
d----         6/18/2020   8:34 PM                5.241.5
d----          5/9/2020   1:05 PM                5.242.2
d----         4/30/2020   4:04 PM                5.244.1
d----         6/17/2020   3:11 PM                5.247.2
d----          6/9/2022   6:20 PM                6.0.0-alpha042
d----         8/15/2021   7:06 PM                6.0.0-beta2
d----         8/15/2021   6:59 PM                6.0.4
d----         6/10/2022  10:25 AM                7.1.5


~
λ

Known workarounds

Please provide a description of any known workarounds.

Activity

  1. smoothdeveloper commented on Jul 6, 2022

    @smoothdeveloper
    Contributor

    @aggieben FYI, this is the logic to find it:

    // we try to resolve .paket/paket.exe any place up in the folder structure from current script
    match findPaketExe prioritizedSearchPaths (DirectoryInfo scriptDir) with
    | Some paketExe -> paketExe
    | None ->
    let nugetDirs =
    let nugetDir = DirectoryInfo(Path.Combine(userProfile, ".nuget", "packages", "paket"))
    if not nugetDir.Exists then
    Seq.empty
    else
    nugetDir.GetDirectories()
    |> Seq.map (fun d ->
    let splits = d.Name.Split('.','-')
    let numberSplits =
    [|
    for split in splits do
    match Int32.TryParse split with
    | false,_ -> Choice2Of2 split
    | true, v -> Choice1Of2 v
    |]
    d, numberSplits)
    |> Seq.sortByDescending snd
    |> Seq.map fst
    |> Seq.map (fun d -> Path.Combine(d.FullName, "tools"))
    let locations =
    [
    Path.Combine(userProfile, PM_DIR)
    Path.Combine(userProfile, ".dotnet", "tools")
    yield! nugetDirs
    ]
    |> Seq.allPairs ["paket"; "paket.exe"]
    |> Seq.map (fun (name, dir) -> Path.Combine(dir, name))
    let result = locations |> Seq.tryFind File.Exists
    match result with
    | Some paketExe -> paketExe
    | None ->
    let foldersTried =
    locations
    |> Seq.map FileInfo
    |> Seq.map (fun f -> sprintf " - %s" f.DirectoryName)
    |> String.concat Environment.NewLine
    failwithf "Paket was not found in '%s' or a parent directory, or in those folders:\n\n%s\n\nPlease download the tool and place it in one of the locations."
    scriptDir foldersTried

    maybe you could try to execute the same logic in your environment and come up with a patch for the implementation?

    let nugetDirs =
      let nugetDir = DirectoryInfo(Path.Combine(userProfile, ".nuget", "packages", "paket"))
      if not nugetDir.Exists then
        Seq.empty 
      else
        nugetDir.GetDirectories() 
        |> Seq.map (fun d -> 
          let splits = d.Name.Split('.','-')
          let numberSplits =
            [|
              for split in splits do
                match Int32.TryParse split with
                | false,_ -> Choice2Of2 split
                | true, v -> Choice1Of2 v
            |]
          d, numberSplits)
        |> Seq.sortByDescending snd
        |> Seq.map fst
        |> Seq.map (fun d -> Path.Combine(d.FullName, "tools"))
  2. smoothdeveloper commented on Jul 6, 2022

    @smoothdeveloper
    Contributor

    I think the reason it fails is that a version which has a - will give a Choice2of2 in a list, which will put it before any other version which has only Choice1of2 in it.

    It looks faulty indeed.

  3. aggieben commented on Jul 7, 2022

    @aggieben
    Author

    Yeah, that's what I found as well. I've been playing around with it in FSI for a while and honestly I'm not sure it's really worth trying to do something sophisticated like full-on semver ordering. The simplest workaround in my particular case would be to update all my dotnet tool manifests to use the latest stable paket (or at least just delete the prerelease versions that are fouling up this ordering).

  4. aggieben commented on Jul 7, 2022

    @aggieben
    Author

    One approach that would avoid this issue might be to change
    Seq.sortByDescending snd to Seq.sortByDescending (snd >> Seq.take 3)

  5. smoothdeveloper commented on Jul 7, 2022

    @smoothdeveloper
    Contributor

    I'll try to fix it, thanks for the report @aggieben!

  6. added a commit that references this issue on Jul 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions