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

Goals #1

Closed
MangelMaxime opened this issue Apr 25, 2024 · 0 comments
Closed

Goals #1

MangelMaxime opened this issue Apr 25, 2024 · 0 comments

Comments

@MangelMaxime
Copy link
Member

Packaging a Fable library requires several requirements which are easy to forget and could be automated by having a custom MSBuild SDK.

Reference for authoring a Fable library

Package Name

I am proposing Fable.Package.SDK to avoid the confusion between Library and Binding.

Library or Binding ?

When creating a Fable package, the first thing to decide is whether this is a library or a binding.

Binding

If the user indicates that this is a binding the only things we need to do is to add fable;fable-binding to the <PackageTags>.

Library

If the user indcates that this is a library then we have more things to setup:

  1. Add fable;fable-library to the <PackageTags>

  2. Add instruction to include the F# source files in the .fable folder:

    <!-- Add source files to "fable" folder in Nuget package -->
    <ItemGroup>
        <!-- Include all files that are compiled with this project -->
        <Content Include="@(Compile)" Pack="true" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
        <!-- Include the project file itself as well -->
        <Content Include="$(MSBuildThisFileFullPath)" Pack="true" PackagePath="fable/" />
    </ItemGroup>
  3. We could also offers the possibility to the user to indicates that he needs to include native files.

    <ItemGroup>
        <!-- Your F# code is already included because of the previous rules, so you only need to ensure the .js files are included as well -->
        <Content Include="**/*.js" Exclude="**\*.fs.js" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
    </ItemGroup>

    For this point, perhaps we could also include the rule to have native files included for all Fable supported target like that the user have one less choice to make. At worth, we would end up included files that are never used which is not too harmful I believe.

Good practices

In the SDK, we could check if the following tag are set and if not we could include the following values for them.

@baronfel Is there a case were we it would be harmful to set this tags if there are not defined?

<PropertyGroup>
   <!-- Ensure debugging information is easily found, so that editors can locate the source code locations for your library.
        This slightly increases the size of your package, but the usability benefits are worth it. -->
   <DebugType>embedded</DebugType>
   <!-- Ensure that files that are generated during the build by the .NET SDK are also included in your compiled library. -->
   <EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>

Tags validation

When packaging a Fable package, it is recommended to include special tags to indicate which runtime is support by the library fable-python, fable-javascript, fable-all etc.

There should always be at least one of this tags present. So we could make the packaging fails if at least one of them is not present.

Note

We could perhaps use these tags to know which native files import rules should be activated but I don't think this is worth it

Usage

Authoring a Fable package would become something like:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
    <!-- ... -->
    <FablePackage>
        <!-- One of these -->
        <PackageType>Library</PackageType> 
        <!-- or -->
        <PackageType>Binding</PackageType>

        <IncludeNativeFiles>true</IncludeNativeFiles> <!-- If we offer an option to control native files inclusion -->
    </FablePackage>
    <ItemGroup>
        <PackageReference Include="Fable.Package.SDK" Version="1.0.0" PrivateAssets="all" />
    </ItemGroup>
</Project>

instead of

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
    <!-- ... -->
    
    <!-- Include F# source files -->
    <ItemGroup>
        <Content Include="@(Compile)" Pack="true" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
        <Content Include="$(MSBuildThisFileFullPath)" Pack="true" PackagePath="fable/" />
    </ItemGroup>
    <!-- Includes native files if needed -->
    <ItemGroup>
        <!-- Your F# code is already included because of the previous rules, so you only need to ensure the .js files are included as well -->
        <Content Include="**/*.js" Exclude="**\*.fs.js" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
    </ItemGroup>
    <!-- Remember to set all the tags -->
    <PropertyGroup>
        <PackageTags>fable;fable-binding;fable-javascript</PackageTags>
    </PropertyGroup>
</Project>

As you can see there are a lot less intimidating syntax and we also have the ability to guide a little bit more the user experience by checking tags validity etc.


When asking @baronfel if this is was something possible to do via a MSBuild SDK he said that yes:

This is very possible, this is the kind of thing I was suggesting as a 'next step' a few months back when I made that docs PR. The questions for me are

  • How do fable packages get built? Does the fable compiler itself create a package, or does the entire process delegate to 'dotnet pack', or something else?
  • Is there a nuget package that already exists that this logic should be shipped inside? If not it's quite easy to create one, but then you need to get Fable users to add a new package.
  • Finally you'd need to figure out the semantics of the changes that you want to add. I don't think anything you've mentioned above is too hard to do, the harder part would be figuring out which Target to run your validation logic before.

As far as actually making the package if there's no existing package I'd suggest:

@dbrattli @ncave Do you see anything else that we should change or improve in this potential Fable SDK ?

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

No branches or pull requests

1 participant