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

[WIP]Adding paket package resolution to fsi and VF# editor #2483

Closed
wants to merge 46 commits into from

Conversation

forki
Copy link
Contributor

@forki forki commented Feb 24, 2017

This is "experimental concept development" for fsharp/fslang-suggestions#542

@dsyme says: We are investigating techniques to implement integrated package management into the F# scripting model. This is experimental and won't be integrated in its current form, but is useful as a proof-of-concept.

The topic is discussed on the thread above.

@forki forki force-pushed the paket branch 2 times, most recently from 6604c36 to 0f5194a Compare February 24, 2017 12:55
@forki forki changed the title [WIP] Addin "#r paket: " support to fsi [WIP] Adding "#r paket: " support to fsi Feb 24, 2017
@smoothdeveloper
Copy link
Contributor

@forki I wonder to resolve the paket.dependencies / .paket folder, if we could instead crowl up the directory structure and only resort to temporary place when no paket.dependencies / .paket folder were found?


let resolvePaket ctok istate errorLogger m =
if not needsPaketInstall then istate else
let paketExePath = @"D:\temp\fsi\.paket\paket.exe"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could there be a directive to specify this location before anything else? Perhaps the default could be the local directory + .paket/paket.exe, or search directories upwards to look for a paket.exe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep this will need to evolve into bootstrapper layer

@forki
Copy link
Contributor Author

forki commented Feb 24, 2017

Yes that would ensure that you get all the deps that are already in the deps file ootb.
We just need something like "#r paket:" to activate the install switch

@dsyme
Copy link
Contributor

dsyme commented Feb 24, 2017

Yep this will need to evolve into bootstrapper layer

I'm not sure we would need a bootstrapper layer in the first case (if that means hot-updating paket.exe?) - editor integration for this logic plus a good error message saying "put paket.exe in a parent .paket directory " would be enough. I suppose if paket.bootstrapper.exe exists we could run it, maybe that's what you mean by a bootstrapper.

@@ -1859,20 +1861,57 @@ type internal FsiInteractionProcessor
stopProcessingRecovery e range0
None

let tempDir = @"D:\temp\fsi"
let paketPrefix = "paket: "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[<Literal>]?

@@ -1859,20 +1861,57 @@ type internal FsiInteractionProcessor
stopProcessingRecovery e range0
None

let tempDir = @"D:\temp\fsi"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System.Environment.ExpandEnvironmentVariables "%TEMP%\fsi"?

@@ -1859,20 +1861,57 @@ type internal FsiInteractionProcessor
stopProcessingRecovery e range0
None

let tempDir = @"D:\temp\fsi"
let paketPrefix = "paket: "
let paketExePath = @"D:\temp\fsi\.paket\paket.exe"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.Combine(tempDir, ".paket", "paket.exe")

let p = Process.Start(startInfo)
p.WaitForExit()
if p.ExitCode <> 0 then
failwithf "Paket restore failed."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need more info here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Though it's just a hack right now :) I'm going to iterate on it to make it activate at design-time

@isaacabraham
Copy link
Contributor

Any reason why we just don't go for a #paket node rather than something explicitly coupled to #r? I suppose I could see #load being used in the same way (for Paket to read from GitHub etc.) but maybe putting it right at the top level could open up possibilities for adding features to F# scripts aside from just reference and load?

@cartermp
Copy link
Contributor

cartermp commented Feb 24, 2017

(Side note: should we split out an issue to discuss this in parallel with this PR?)

There is also the .NET Core vector to consider here. Note that one of the problems @KevinRansom is looking into affects this. For example, assume that FSI loads System.Runtime v4.1.0. Somewhere in the script, a paket reference pulls in System.Runtime v4.1.1 via a transitive dependency. This could cause any number of problems. We already have this issue today with directly referencing an assembly via #r. There are a number of ways to approach this:

  1. Fail to reference the paket reference (or assembly reference), citing a version number issue in the error message.
  2. Restart the FSI process and load the higher version of the assembly
  3. Attempt to re-calculate assemblies to reference on the fly

This poses a problem given how assemblies are laid out on disk in a .NET Core world, and assumptions in this area for the current FSI implementation need to be teased out and rewritten. It's going to be quite a bit of work and we're not confident we know the correct solution here. My question is:

Does Paket affect this beyond possibly pulling in a different assembly version than what is currently loaded in an FSI process? If we're to take this change (I support taking it, BTW), then we'll have to make sure we can still solve the current problem we have in a .NET Core 2.0 timeframe. Otherwise, we'll be shipping an FSI which has an additional vector with which you can have issues with assembly references.

@forki
Copy link
Contributor Author

forki commented Feb 24, 2017

This is just WIP for the language design issue fsharp/fslang-suggestions#542 - It's not ready for the real deep engineering questions. Please discuss in the language design issue.

@forki
Copy link
Contributor Author

forki commented Feb 24, 2017

@enricosada it seems .NET core doesn't like

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

what do we use instead?

@matthid
Copy link
Contributor

matthid commented Feb 24, 2017

@forki I used an environment variable in my netcore ports (fake/paket). this is probably one of the apis comming back with netstandard 2.

@forki
Copy link
Contributor Author

forki commented Feb 24, 2017

Can you please send a pull request to my fork here or just link to the line in paket? Really appreciate it. Didn't find it yet

@dsyme
Copy link
Contributor

dsyme commented Feb 25, 2017

@cartermp - Yes, this is just an experiment. Don’t even bother looking at it. We’re mucking about to see what integrated package management might look like. We’re not seriously going to even suggest pulling that PR in anything remotely like its current form. I'm just working with @forki to hack through a demonstrator.

My suggestion is that we just label the PR as “Totally Experimental” and you can safely ignore it.

It's my opinion that whatever we do here must work on both .NET Framework and .NET Core. We shouldn’t commit to anything in this space until .NET Core scripting is done, and we have a solution that works for both .NET Core and .NET Framework.

@dsyme dsyme changed the title [WIP] Adding "#r paket: " support to fsi [Totally Experimental] Adding "#r paket: " support to fsi Feb 25, 2017
@dsyme
Copy link
Contributor

dsyme commented Feb 25, 2017

@forki To be honest we should probably close this PR and work from your branch until we're done with mucking about.

@dsyme
Copy link
Contributor

dsyme commented Feb 25, 2017

@isaacabraham

Any reason why we just don't go for a #paket node rather than something explicitly coupled to #r?

Let's discuss on the fslang-suggestion.

@@ -4624,8 +4624,7 @@ let RequireDLL (ctok, tcImports:TcImports, tcEnv, thisAssemblyName, m, file) =
let tcEnv = (tcEnv, asms) ||> List.fold (fun tcEnv asm -> AddCcuToTcEnv(g,amap,m,tcEnv,thisAssemblyName,asm.FSharpViewOfMetadata,asm.AssemblyAutoOpenAttributes,asm.AssemblyInternalsVisibleToAttributes))
tcEnv,(dllinfos,asms)


let paketPrefix = "paket: "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was this change about?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, we only want things starting with paket: to be included, right? And we want #r "paket" to be a normal DLL reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I should revert that part. The thing I wanted to support was basically a switch to just activate the paket references from the ambient paket.dependencies that is already existing in the repo. Basically I thought

#r "paket: "

Looks weird, so let's make it

#r "paket" 

But that's something for the language design part. I will use the first version for now.

Some loadScript

| _ ->
File.WriteAllLines(paketDepsFile.FullName, packageManagerTextLines)
Copy link
Contributor

@dsyme dsyme Feb 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to overwrite the existing paket.dependencies

Or was the idea that simply adding #r "paket" would get you the packages listed there? But then what if there are additional packages specified in the script?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the idea was to use the existing file and append to it with additional deps from the script.

@forki
Copy link
Contributor Author

forki commented Feb 25, 2017

@cartermp and @dsyme - I'd like to keep it on this fork since it's the only with CI. And CI already pointed out problems.

@forki forki force-pushed the paket branch 3 times, most recently from fb8c3ab to 66e5ed5 Compare February 25, 2017 10:38
@forki
Copy link
Contributor Author

forki commented Feb 25, 2017

@dsyme I remove the bootstrapper.exe call. With Paket4 we will always use magic mode. https://fsprojects.github.io/Paket/bootstrapper.html#Magic-mode

tldr: we renamed the bootstrapper to paket.exe and it will magically restore the real paket.exe to some appfolder. So you commit 40KB to your repo (as paket.exe) and never worry again. It's magic!

@forki forki closed this Jul 4, 2017
@forki forki reopened this Jul 4, 2017
@ErikSchierboom
Copy link
Contributor

This is great! My primary use case for F# at work is writing scripts with it, and this would be very helpful!

@matthid
Copy link
Contributor

matthid commented Jul 8, 2017

I suggest to add #r "paket: group NetCore" to reference a group of an existing paket.dependencies of the current solution.
This would in best case add all references as specified in the lockfile and in worst case do a install/update to write the lockfile first.

Will probably update FAKE 5 to use this PR and then we can see how it works out in practice.

@forki
Copy link
Contributor Author

forki commented Jul 9, 2017

Yes I think currently we always load main group. That would be weird in FAKE settings. Regarding fake: it's a high risk to add this right now to fake since tooling will not support it and therefore ionide and vs will always show squigglies. Currently it would basically be a fork of the language. I'm not sure if that's a good thing. Unfortunately we don't how long it will take to get it in.
On the other hand most C# builds forked the c# language and people still think it is valuable. I have no good answer here

@matthid
Copy link
Contributor

matthid commented Jul 25, 2017

@dsyme If we can "approve in principle" we could go ahead and test this in the FAKE 5 alpha.
@forki is against a potential fork if we just go ahead and integrate this PR.

This could potentially solve some problems we have in the netcore world in FAKE 5. But obviously we can only be sure if we try to implement it there. Also it would be nice to tell us how this relates to #2667

Maybe it would make more sense for the visualfsharp team to accept this if we can proof that it works in practice with netcore and FAKE 5?

Thanks!

@forki
Copy link
Contributor Author

forki commented Aug 26, 2017

Ping.
We would really like to see this going in or at least e approved so that we can use it in FAKE.
It should not be merged together with .NET core decisions. This is already super useful as is.

@0x53A
Copy link
Contributor

0x53A commented Aug 26, 2017

I know that Microsoft as a Corporation probably has relative strict support and backwards-compatibility requirements, but I would really love if this could be "preview-released" NOW, even if it will be broken later.

Otherwise I fear that we will repeat this discussion in a year or two from now.

I think we will trip over so many issues, that at least one breaking-change release will be required anyway.

My suggestion would be to either enable this behind an extra flag (fsi --enable-experimental-package-support) or print a (hidable with a different flag) warning if the parser encounters a usage.

This would make it absolutely clear that there are no support guarantees, but still enable us to use this and gather experience.

@KevinRansom
Copy link
Member

I am so very, very sorry about this. it's on the list.

@realvictorprm
Copy link
Contributor

Ping :-)

@dsyme
Copy link
Contributor

dsyme commented Dec 1, 2017

Closing in favour of #4042

(@KevinRansom @forki is this correct?)

@dsyme dsyme closed this Dec 1, 2017
@forki
Copy link
Contributor Author

forki commented Dec 1, 2017 via email

@dsyme
Copy link
Contributor

dsyme commented Dec 1, 2017

@forki Either way we'd do that as a separate PR over #4042 right?

@KevinRansom
Copy link
Member

@forki I agree that paket should be in the box. But it will certainly be a separate PR. Thinking about it I expect the nuget package manager will be a separate PR too. This PR should probably handle the extensibility and the wiring, and the actual implementations of specific packagemanagement should follow!

@KevinRansom KevinRansom reopened this Dec 1, 2017
@KevinRansom
Copy link
Member

I would like to keep this open for reference pls.

@KevinRansom KevinRansom changed the title Adding paket package resolution to fsi and VF# editor [WIP]Adding paket package resolution to fsi and VF# editor Dec 7, 2017
@cartermp
Copy link
Contributor

cartermp commented Nov 1, 2018

Closing in favor of #5850 which uses the same core mechanism

@cartermp cartermp closed this Nov 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.