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

Experiment with MSBuild DesignTime #3721

Merged
merged 18 commits into from Feb 12, 2024
Merged

Experiment with MSBuild DesignTime #3721

merged 18 commits into from Feb 12, 2024

Conversation

MangelMaxime
Copy link
Member

This PR is based on #3720

@nojaf I tried to have a look at integrating MSBuild DesignTime instead of BuildAnalyzer.

But it seems like we are doing something incorrectly because it is not able to compile Fable.Library.fsproj

Fable.Build: dotnet run -c Release --project /Users/mmangel/Workspaces/Github/fable-compiler/Fable/src/Fable.Build/../Fable.Cli -- src/fable-library --outDir temp/fable-library-ts --fableLib ./temp/fable-library-ts --lang typescript --exclude Fable.Core --define FABLE_LIBRARY --noCache --typedArrays false --define FX_NO_BIGINT
Fable 4.10.0: F# to TypeScript compiler
Minimum fable-library version (when installed from npm): 1.1.1

Thanks to the contributor! @7sharp9
Stand with Ukraine! https://standwithukraine.com.ua/

Parsing src/fable-library/Fable.Library.fsproj...
src/Fable.Core> dotnet build -c Release
MSBuild version 17.8.3+195e7f5a3 for .NET
  Determining projects to restore...
  Restored /Users/mmangel/Workspaces/Github/fable-compiler/Fable/src/Fable.Core/Fable.Core.fsproj (in 105 ms).
  Fable.Core -> /Users/mmangel/Workspaces/Github/fable-compiler/Fable/src/Fable.Core/bin/Release/netstandard2.0/Fable.Core.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.97
Project and references (18 source files) parsed in 3255ms

Started Fable compilation...
Compiled 18/18: Map.fsFable compilation finished in 289ms

./Global.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./SystemException.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./System.Text.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./System.Collections.Generic.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./FSharp.Collections.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./FSharp.Core.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Native.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./MutableMap.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./MutableSet.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Choice.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Array.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./List.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Seq.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Seq2.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Range.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Random.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
./Set.fs(1,1): (1,1) error FSHARP: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. (code 222)
Compilation failed

@nojaf
Copy link
Member

nojaf commented Jan 29, 2024

Cracking at first glance worked on my end.
I do notice that the file paths are relative in the output.
That might be the problem, the source cannot be read and leads to the parsing bugs you see in the output.

I'll take a look at this later today.

PS: A quick easy way to find out if cracking at least worked is by using this script.

@nojaf
Copy link
Member

nojaf commented Jan 29, 2024

Just update the source to use the full path. If you can easily try it, give it a go I'd say.

@nojaf
Copy link
Member

nojaf commented Jan 29, 2024

@MangelMaxime I couldn't help myself, after this last change ./build.sh fable-library --javascript worked for me locally.

@nojaf
Copy link
Member

nojaf commented Jan 29, 2024

There still are some gaps in this new resolver mechanism.
Better error handling is one of them.
I still very much believe the core idea holds, it just needs some more work to perfect it.
Also, there is no caching in place yet, I would not ship this without that. (I do have some ideas on that though).

@MangelMaxime
Copy link
Member Author

Thank you for looking into it.

It seems like this is working for some scenario like the ./build.sh quicktest javascript but not when running the full test suite ./build.sh test javascript

Seems like this is not a as easy quick win as I was thinking, I think for today I will release a new version based on #3720 which workarounds the limitation we have with the current system.

But I think we should continue to push the MSBuildDesign time work as this will hopefully be more robust and remove the workaround that we need to introduce ATM.

If I can help we anything please tell me.

@nojaf
Copy link
Member

nojaf commented Jan 29, 2024

Yup, this still needs some more love. Once we figured everything out for Fable itself and added some caching, we should play around with the feature toggle. Allow users to switch between this new thing and Buildalyzer.

@MangelMaxime
Copy link
Member Author

I updated the PR to change the name of the cracker file and also to include the latest changes I introduced in main.

@@ -971,6 +976,10 @@ let private checkRunProcess (state: State) (projCracked: ProjectCracked) (compil
| _, exeFile -> exeFile, runProc.Args

if Option.isSome state.Watcher then
printfn "cliArgs.RunProcessEnv: %A" cliArgs.RunProcessEnv
Copy link
Member

Choose a reason for hiding this comment

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

Is this still required?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably not, I think it is me debugging something (if it me who added this code).

I think you also mentioned that for Vite we should not write directly to the console as it will mess up communication between processes.

Copy link
Member

Choose a reason for hiding this comment

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

Well in Fable.Cli that wouldn't be a problem as that doesn't end up in the Vite plugin.
But since we introduced the logger, it feels wrong to ever use printfn again.
The lines are yours, I would remove them if we no longer need them.

@nojaf
Copy link
Member

nojaf commented Feb 12, 2024

@MangelMaxime I think this is in a good state now to release behind an experimental flag.
What do you think?

@MangelMaxime
Copy link
Member Author

@MangelMaxime I think this is in a good state now to release behind an experimental flag.

Sorry didn't see that CI was green now.

Yes we can release it by introducing a new Flag to Fable CLI to control the switch between build-analyzser and msbuild

We could do it with something like:

  • --msbuild or --msbuild-cracker
  • --cracker=msbuild or - --cracker=build-analyzser

What do you think? Once we decide a the flag, if you want I can adapt the PR for it.

@nojaf
Copy link
Member

nojaf commented Feb 12, 2024

The F# compiler prefixes its test arguments with test:? What do you think of that?
Something like --test:msbuild-cracker?

@MangelMaxime
Copy link
Member Author

The F# compiler prefixes its test arguments with test:? What do you think of that?
Something like --test:msbuild-cracker?

Yes we can follow F# compiler naming and the suggested flag looks good to me.

@nojaf
Copy link
Member

nojaf commented Feb 12, 2024

Add a CLI flag for this, went with --test:MSBuildCracker, the casing feels more consistent with the rest.

I also didn't include this property in CliArgs as it is tied Fable.Cli and isn't used in the compiler. That being said CliArgs isn't really a good name anymore.

Feel free to tweak things here.

@MangelMaxime
Copy link
Member Author

Add a CLI flag for this, went with --test:MSBuildCracker, the casing feels more consistent with the rest.

Thank you. In reality, the casing is only respected when printing the help message.

Because when looking for the value in the arguments list, the code lower the value (that's one of the reason I also want to rewrite Fable.CLI in general casing in CLI should be respected IHMO).

member _.Value([<ParamArray>] keys: string array) =
keys
|> Array.map (fun k -> k.ToLower())
|> Array.tryPick (fun k -> Map.tryFind k argsMap)
|> Option.bind List.tryHead

That being said CliArgs isn't really a good name anymore.

We will handle that when rewriting Fable.Cli. With the number of things that we are starting to accumulate on that subject, I think it will be my next big task for Fable.

@MangelMaxime MangelMaxime merged commit 53238bc into main Feb 12, 2024
19 checks passed
@MangelMaxime MangelMaxime deleted the msbuild_design_time branch February 12, 2024 20:57
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.

None yet

2 participants