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

paket dependency manager doesn't work out of the box in VS, but it does if compiles with VS #12895

Open
smoothdeveloper opened this issue Mar 29, 2022 · 11 comments
Labels
Area-SetupAndDelivery Setup, packages, templates, SDK, delivery channels Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code.
Milestone

Comments

@smoothdeveloper
Copy link
Contributor

smoothdeveloper commented Mar 29, 2022

When I pull the release of FSharp.DependencyManager.Paket.dll from https://github.com/fsprojects/Paket/releases and drop it next to the location it is required under dotnet fsi (under the dotnet sdk folder, next to the nuget extension), it just works.

However, when I attempt to do so, in order for VS to pick it up, dropping under the commonextensions/microsoft/fsharp folder, VS doesn't pick it up.

Repro steps

  • download FSharp.DependencyManager.Paket.dll from https://github.com/fsprojects/Paket/releases
  • (§) drop it in your VS installation (C:\Program Files\Microsoft Visual Studio\2022\Preview\Common7\IDE\CommonExtensions\Microsoft\FSharp for example)
  • open a script with #r "paket: nuget Foo" in it

Expected behavior

Typechecks or complains about the file being locked by the OS, and guide the user to fix it.

Actual behavior

Complains about the extension "paket" not being present.

Actual manual fix

check that the extension assembly file is not blocked by the OS (due to being downloaded from browser or other reasons).

Initial workaround

FSharp.DependencyManager.Paket.release.zip

Related information

It always behaved this way, it is not something which broke due to a change, but it should be fixed if possible.

I suspect it impacts any other extensions than the one which Microsoft ships, I don't know why it works out of the box in the dotnet sdk but not in VS.

@KevinRansom
Copy link
Member

This is supposed to work. Assuming that the packet package manager is implemented correctly. Which I am sure it is.

@KevinRansom
Copy link
Member

I will take a look when I get a chance.

@smoothdeveloper
Copy link
Contributor Author

Thanks @KevinRansom and hit me up if anything.

It would be good to have @KathleenDollard & all think about end user experience (I know the prospect of extensions as powerful as type providers, being like a pandora box, is not the best for restful nights) and some technicals, like some old ideas in #8880.

I was thinking having a "open folder to fsharp VS extension" under the F# Interactive settings, with "use at your own risk" (as it requires admin rights for writing in the folder) and note about putting the same extensions under the dotnet sdk.

Most VS users will need to drop the extensions manually in two folders, or more, so in long run, it makes it tedious for developers and end users (those that write scripts) to manage the extensions from their IDE, and I'd like to asses what Microsoft wants to happen on that end.

Thanks all.

@dsyme dsyme added Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code. Area-SetupAndDelivery Setup, packages, templates, SDK, delivery channels labels Apr 4, 2022
@dsyme
Copy link
Contributor

dsyme commented Apr 4, 2022

We should have a design document (e.g. tooling RFC) that specifies how the DependencyManager things work. It's hard to tell what the intended design is.

@smoothdeveloper
Copy link
Contributor Author

@dsyme, it does work the same as the Nuget extension (the .dll of an extension should be next to it), this is the spec for now, and --compilertool: is used if you need to store the extension in adhoc location.

Microsoft shipped "#r "nuget:"" but not what was underlying getting it, or the spec of the RFC, yet, it is clear, extensions work like the one that ships and is supported by Microsoft.

I have clarified the RFC: fsharp/fslang-design#659

I am eager the whole thing evolve, to something as great as installing vscode extensions in major IDEs, and ideally, that there is a stable location, and documented behaviour about how the loading of extension takes place, but it will be hard for me to nudge it, and I am preoccupied about my own ability to use the extensions and to engage with community to write more of them.

If this issue is not fixed, no one has much incentive to work on extensions (in F# community, it can take place without need of official documentation being perfect, it works for the compiler for example) IMO.

If there are no extensions (beside paket, justifying it is technically true, it is extensible), I doubt Microsoft is going to pour effort in the user experience to install extensions.

@smoothdeveloper
Copy link
Contributor Author

Current status:

image

I am forced to recompile the extension locally with each release/update of VS and there are 3 or 4 locations to put it, to get it to work on all the places it is needed:

  • Common7/IDE or CommonExtensions/.../FSharp
  • FSharp/Tools
  • dotnet sdk

IMO, it makes extension in scripting context unusable.

I assume it is a missing handling for FSharp.Core binding redirect through https://docs.microsoft.com/en-US/dotnet/api/system.appdomain.assemblyresolve?view=net-6.0 that would make it work in VS.

@smoothdeveloper
Copy link
Contributor Author

@dsyme, questioning the "impact: low", it is like there is not much interest in seeing the extension mechanism being put into use, or that #r "nuget: " is all that was required. Those are false assertions.

@dsyme
Copy link
Contributor

dsyme commented Jul 6, 2022

@smoothdeveloper I'll let @KevinRansom decide on the priority and direction here.

It's true I'm now a more skeptical of the long-term viability or wisdom of supporting an extensible model of resolution - especially anything that involves globally installed tools or tools not managed via "dotnet tool" (which wasn't available when we first started this). Also the unexpectedly relatively low activity in the Paket repo in the last year makes me wonder about the scenario now - I mean the tool is maintained and available but the updates to .NET 6 took some time and as a result of the role out of .NET SDK projects it is no longer as influential on the F# community and practice as it was.

That's just my 2c worth. The extension point is part of the overall feature set we have and it makes sense to make it work in all reasonable scenarios. And it's quite possible the extension point could itself be extended and come in handy for other things.

@vzarytovskii vzarytovskii added this to the Backlog milestone Jul 7, 2022
@smoothdeveloper
Copy link
Contributor Author

@dsyme, thanks for sharing your standpoint.

Regarding paket activity, it is in maintenance mode, but I doubt it goes away, and it is widely used, even with dotnet SDK (and PackageReference), it still provide functionality and aspects that aren't doable without it, and are simpler than what Microsoft is designing with nuget.

For example, I just noticed fantomas repository uses it to avoid taking binary dependency on FCS (quite clever, to shorten feedback loop, etc.), I can't myself work much without it in projects involving lots of dependencies, etc.

Also the breadth of contributors that open issues and fix them themselves or get a quick fix by seasoned maintainers is good testimony of durability of the tool.

The paket extension itself is super useful, and I can see other useful extension in the making, that would really bring value to F# scripting, only the deployment story is less than ideal (#8880 has few pointers, and we could discuss).

#r "roslyn: path.to.vb"
#r "msbuild: path/to/file.proj"
#r "cppsharp: path/to/include.hpp"

The paket extension does stuff that nuget can't do (file dependencies, git/github dependencies, etc.).

Proposed action plan:

  1. to get the extension that are already compiled and shipping to work just by dropping it in the folders VS expects it (this issue).
  2. start shipping the nuget extension in another location, which will be a supported location not involving messing with dotnet sdk and VS install folders (Uninstall of SDK leaves trailing files which trips VS sdk#26474), and have dotnet fsi and VS and FCS looking for this location (DependencyProvider: Add a stable path which is tooling independent  #8880).
  3. maybe loading extension from referenced assemblies in FSI (highlighted in #8880).
  4. adjusting documentation and adding guidelines to write extensions

Extensions could eventually contribute more things to FSI, providing a packaged approach to setup pretty printers, useful for notebooks, etc. But first it is required to make them easy to install.

I don't mind it takes a route that involves dotnet as frontend, but I am concerned that point 1 is still blocking the most to make it useful to end users.

@smoothdeveloper
Copy link
Contributor Author

The issue stems from the binary file being "blocked" by the OS. I was able to troubleshot this with debugger and seeing the inner exceptions messages.

Would the fsharp team take a PR that:

  • replaces
    let enumerateDependencyManagerAssemblies compilerTools (reportError: ResolvingErrorReport) =
    getCompilerToolsDesignTimeAssemblyPaths compilerTools
    |> Seq.append (assemblySearchPaths.Force())
    |> Seq.collect (fun path ->
    try
    if Directory.Exists(path) then
    Directory.EnumerateFiles(path, dependencyManagerPattern)
    else
    Seq.empty
    with _ ->
    Seq.empty)
    |> Seq.choose (fun path ->
    try
    Some(Assembly.LoadFrom path)
    with e ->
    let e = stripTieWrapper e
    let n, m = FSComp.SR.couldNotLoadDependencyManagerExtension (path, e.Message)
    reportError.Invoke(ErrorReportType.Warning, n, m)
    None)
    |> Seq.filter (fun a -> assemblyHasAttribute a dependencyManagerAttributeName)
    with non lazy code (this is amortized, and makes debugging this stage easier)
  • displays the messages of all the exception tree rather than just the top one

?

Also, I'd like that either the compilertool parameter given to FSI becomes used by the compiler service so end users could install the assemblies where they want and adjust a single setting for both FSI and the tooling, while currently, they need to deploy the assembly at two spots (one for the fsi binary, one for VS), will the team consider such change?

@smoothdeveloper
Copy link
Contributor Author

@baronfel, do you know if an API exists in the various .NET runtimes (the ones for Visual Studio, FsiAnyCPU.exe and dotnet fsi) uses that would allow to check, on Windows, if a .dll file is locked by the OS for security reasons?

I'd like FSI and the tooling to report the specific error and provide guidance to the user when Windows defender / internet browser blocks a downloaded extension.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-SetupAndDelivery Setup, packages, templates, SDK, delivery channels Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code.
Projects
Status: New
Development

No branches or pull requests

4 participants