Git Product home page Git Product logo

femto's Introduction

Femto Nuget

Femto is CLI tool that manages the npm/python packages used by Fable bindings. It installs them using the package manager that you are using whether that is:

  • npm (default)
  • yarn when yarn.lock is found
  • pnpm when pnpm-lock.yaml is detected
  • poetry when pyproject.toml is detected

Read Introducing Femto for an in-depth understanding of why Femto is needed and what problem it solves.

Install

dotnet tool install femto --global

Project Dependency Analysis

Simply cd your way to the directory where you have your Fable application and run

femto

Alternatively, you can specify a project file by yourself:

femto ./Client.fsproj

Here is an example output (note package.json can be alongside the project or in a directory above):

c:\projects\elmish-getting-started\src> femto
[18:17:09 INF] Analyzing project c:/projects/elmish-getting-started/src/App.fsproj
[18:17:11 INF] Found package.json in c:\projects\elmish-getting-started
[18:17:11 INF] Using npm for package management
[18:17:14 INF] Elmish.AnimatedTree requires npm package react-spring
[18:17:14 INF]   | -- Required range >= 8.0.0 found in project file
[18:17:14 INF]   | -- Used range ^8.0.1 in package.json
[18:17:14 INF]   | -- Found installed version 8.0.1
[18:17:14 INF]   | -- react-spring was installed into "devDependencies" instead of "dependencies"
[18:17:14 INF]   | -- Re-install as a production dependency
[18:17:14 INF]   | -- Resolve manually using 'npm uninstall react-spring' then 'npm install [email protected] --save'
[18:17:14 INF] Fable.DateFunctions requires npm package date-fns
[18:17:14 INF]   | -- Required range >= 1.30 < 2.0 found in project file
[18:17:14 INF]   | -- Missing date-fns in package.json
[18:17:14 INF]   | -- Resolve manually using 'npm install [email protected] --save'
[18:17:14 INF] Elmish.SweetAlert requires npm package sweetalert2
[18:17:14 INF]   | -- Required range >= 8.5 found in project file
[18:17:14 INF]   | -- Missing sweetalert2 in package.json
[18:17:14 INF]   | -- Resolve manually using 'npm install [email protected] --save'

Automatic Package resolution with --resolve

Femto can automagically resolve required package issues using the command --resolve:

femto --resolve

femto --resolve ./src/Client.fsproj

This command checks for missing packages and packages of which the installed version does not satisfy the required version found in npm dependency metadata of the used Fable packages.

  • If a package is missing then it is installed.
  • If a package version doesn't satisfy requirements, then a proper version is resolved and the package is replaced with the new resolved version by uninstalling the current one and installing the correct package.
  • If a package version doesn't satisfy requirements and a version cannot be resolved that satisfies requirements, then a resolution error is logged.

Installing Packages with femto install <package>

Femto can install a package for a project whether it is using paket or not then automatically resolves the required npm packages afterwards. Simply navigate to a project where there is a fsharp/Fable project and call

femto install <package>

First, Femto detects whether it needs to use paket by checking the existence of a paket.references file, if that is the case then Femto also detects in which dependency group the package has to be installed and eventually calls the installed paket instance to install the package. Afterwards, Femto calls --resolve to install potentially required npm packages. When there is no paket.references file, then Femto simply calls dotnet add package <package> and then femto --resolve in the project directory.

When Femto cannot find paket installed as a global dotnet tool nor as a local installation from the paket bootstrapper under .paket/paket.exe, then Femto will install it locally following these Paket gettings started guidelines and restarts the installation process.

Uninstalling Packages with femto uninstall <package>

Same as when installing a package, Femto will instruct either nuget or paket to uninstall the package except this command does not remove unused packages from npm in package.json because Femto cannot know whether the package is being used multiple projects.

Library Authors with JavaScript

In order for Femto to pick up the npm packages that your library depends upon, you must add a section in the project file of your library:

<PropertyGroup>
  <NpmDependencies>
      <NpmPackage Name="date-fns" Version="gt 1.30.0 lt 2.0.0" ResolutionStrategy="Max" />
  </NpmDependencies>
</PropertyGroup>

Notice here in the example, we have one npm package we depend upon which has requires a version that satisfies the range gt 1.30.0 lt 2.0.0 and the resolution strategy is max. This means that Femto will find the version in this current major release with latest bug fixes but nothing in the next release because we cannot assume the binding will still work in the next major release which will most likely contain breaking changes. It is recommended to always follow the format above when specifying the version requirements.

Library Authors with Python

Defining Python dependencies in your project as follows:

<PropertyGroup>
  <PythonDependencies>
    <Package Name="requests" Version="&gt;= 2.28.1 &lt; 3.0.0" ResolutionStrategy="Max" />
  </PythonDependencies>
</PropertyGroup>

Resolution Strategy

You can customize the resolution strategy by adding ResolutionStrategy attribute to an NpmPackage node. Accepted values are min and max (case-insensitive). If ResolutionStrategy is not set, we default to min strategy.

Development Dependency

You can specify whether the npm package your library depends upon is actually a development dependency instead a production dependency using the DevDependency attribute. Package resolution take development dependencies into account and if the developer had installed the package by mistake in production dependencies then the automatic resolver will un-install it and re-install it a development dependency.

<PropertyGroup>
  <NpmDependencies>
      <NpmPackage Name="date-fns" Version="gt 1.30.0 lt 2.0.0" ResolutionStrategy="Max" DevDependency="true" />
  </NpmDependencies>
</PropertyGroup>

Unsupported Version Ranges

Sometimes you want to restrict the version using a specific range such as >= 1.0 < 2 This range cannot be set inside the attribute value of Version because the XML would be invalid and you would not be able to dotnet restore the project. In these cases you can replace the operator with it's abbreviated name:

  • >= becomes gte
  • > become gt
  • <= becomes lte
  • < becomes lt

This way you can specify your version range as gte 1.0 lt 2 or you can mix-and-match the notations >= 1.0 lt 2

Visual Studio Users

If you happen to use Visual Studio to build your library, it will escape symbols like >= or > from the project and turn them into &gt;= or &gt;. Don't worry about this because Femto can still understand the underlying symbols. To make sure everything still works, run femto --validate (see below) against your project and you should see the same results.

Validate your dependencies

If you are a library author and wondering whether Femto will pick up the dependencies you specified in your project file, then simply run:

femto --validate

femto --validate ./path/to/Library.fsproj

In the directory where you have the project file of your library. This command will check whether the library has valid metadata about the required npm packages and will try to resolve the versions based on the specified ResolutionStrategy.

femto's People

Contributors

alfonsogarciacaro avatar cmeeren avatar dbrattli avatar detikpw avatar jooseppi12 avatar jwthomson avatar mangelmaxime avatar nabeelvalley avatar philderbeast avatar semuserable avatar smoothdeveloper avatar stmax82 avatar thisfunctionaltom avatar zaid-ajaj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

femto's Issues

Femto cannot use local paket

  1. Use the latest SAFE.Template
  2. Add femto as a local tool
  3. Restore the tools

Then try to add a package using dotnet femto install, I get:

[12:02:13 INF] Analyzing project /Users/halcwb/Development/Informedica/apps/PediatricRiskCalc/src/Client/Client.fsproj
[12:02:13 INF] Running dotnet restore against the project
[12:02:14 INF] Detected paket.references file -> use paket
[12:02:14 INF] Installing Feliz within dependency group Client
[12:02:14 INF] Using locally installed paket
Unhandled exception. System.Exception: Start of process 'dotnet paket' failed.

But I can do dotnet paket --version. So paket can be run using dotnet.

.NET Core SDK (reflecting any global.json):
Version: 3.1.300
Commit: b2475c1295

Runtime Environment:
OS Name: Mac OS X
OS Version: 10.15
OS Platform: Darwin
RID: osx.10.15-x64
Base Path: /usr/local/share/dotnet/sdk/3.1.300/

Host (useful for support):
Version: 3.1.4
Commit: 0c2e69caa6

.NET Core SDKs installed:
2.1.101 [/usr/local/share/dotnet/sdk]
2.1.302 [/usr/local/share/dotnet/sdk]
2.1.402 [/usr/local/share/dotnet/sdk]
2.1.505 [/usr/local/share/dotnet/sdk]
2.1.700 [/usr/local/share/dotnet/sdk]
2.2.301 [/usr/local/share/dotnet/sdk]
3.0.100 [/usr/local/share/dotnet/sdk]
3.1.100-preview3-014645 [/usr/local/share/dotnet/sdk]
3.1.100 [/usr/local/share/dotnet/sdk]
3.1.101 [/usr/local/share/dotnet/sdk]
3.1.200 [/usr/local/share/dotnet/sdk]
3.1.201 [/usr/local/share/dotnet/sdk]
3.1.202 [/usr/local/share/dotnet/sdk]
3.1.300 [/usr/local/share/dotnet/sdk]

Dotnet doesn't seems to escape correctly the XML attributes

I think dotnet doesn't escape correctly the XML attributes (or perhaps XML spec don't allow to do what I describe next).

If you use < in the version constraint then dotnet can't parse the project...

Take the following fsproj:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <Compile Include="Main.fs" />
    </ItemGroup>
    <PropertyGroup>
    <NpmDependencies>
        <NpmPackage Name="date-fns" Version=">= 1.30.0"/>
        <NpmPackage Name="bulma" Version=">= 0.6.0"/>
        <NpmPackage Name="password-generator" Version=">= 1.0.0 < 2.0.0"/>
    </NpmDependencies>
    </PropertyGroup>
</Project>

If you run dotnet restore, you get:

/Users/maximemangel/Workspaces/Github/Zaid-Ajaj/FemtoTest/NpmPackageNotInstalled/NpmPackageNotInstalled.fsproj(13,65): error MSB4025: The project file could not be loaded. '<', hexadecimal value 0x3C, is an invalid attribute character. Line 13, position 65.

This means we can't support all the SemVer syntax...

Resolve conflicts: requiring same package but for different versions

This scenario is very unlikely to happen but it is possible nonetheless

Resolution conflicts arise when a npm package is being required more than once for different versions. The procedure I am thinking of is simply to resolve a version for each required range and choose the first one that satisfies all input version ranges, otherwise we show an error message

Resolvable conflicts

<NpmDependencies>
  <NpmPackage Name="date-fns" Version=">= 1.0 lt 2.0" ResolutionStrategy="Min" />
  <NpmPackage Name="date-fns" Version=">= 1.30 lt 2.0" ResolutionStrategy="Max" />
</NpmDependencies>

Resolved version 1.30.1 satisfies both requirements and thus can be installed

Unresolvable conflicts

<NpmDependencies>
  <NpmPackage Name="date-fns" Version=">= 1.0 lt 1.30" ResolutionStrategy="Min" />
  <NpmPackage Name="date-fns" Version=">= 1.30 lt 2.0" ResolutionStrategy="Max" />
</NpmDependencies>

Different versions will be resolved [ 1.0, 1.30.1 ] but neither will satisfy both required version ranges, in this case, Femto will show an error recommending to contact the library author to update his/her package

If no Femto metadata found don't log as a warning

If no metadata found don't log as a warning it can be normal. For example, when checking the transitive dependencies it's normal that some packages don't have them.

It's also "normal" that the user project doesn't have the Femto metadata if it's not a library.

[16:19:22 WRN] Project Fulma.Elmish does not contain npm dependency metadata

Femto doesn't work if the project is in a sub folder

If you try running femto from the root of Fable.React repo it fails to analyze the project.

If I move under src folder then it's working.

Logs:

โžœ  fable-react git:(master) โœ— femto validate src/Fable.React.fsproj
[09:03:42 INF] Analyzing project src/Fable.React.fsproj
[09:03:43 ERR] Error while analyzing project structure and dependencies
โžœ  fable-react git:(master) โœ— cd src 
โžœ  src git:(master) โœ— femto validate Fable.React.fsproj 
[09:05:02 INF] Analyzing project Fable.React.fsproj
[09:05:05 INF] Found package.json in /Users/maximemangel/Workspaces/Github/fable-compiler/fable-react
[09:05:05 INF] Npm packages need to be restored first for project analysis
[09:05:05 INF] Restoring npm packages using 'npm install' inside /Users/maximemangel/Workspaces/Github/fable-compiler/fable-react
[09:05:10 INF] Analyzing project Fable.React.fsproj
[09:05:12 INF] Found package.json in /Users/maximemangel/Workspaces/Github/fable-compiler/fable-react
[09:05:12 INF] Using npm for package management
[09:05:13 INF] Fable.React requires npm package react
[09:05:13 INF]   | -- Required range >= 16.8.0 found in project file
[09:05:13 INF]   | -- Missing react in package.json
[09:05:13 INF]   | -- Resolve manually using 'npm install [email protected] --save'

Add params to toggle verbose/non verbose mode

I find the current logs really helpful to identify what is being done. However, if you have a lot of dependencies, it can quickly become hard to read because of the noise.

I think we could just log the dependencies that are failing and have a summary at the end.

Fulma depends on npm package 'bulma':
...
...

Femto 10 dependencies checked for 9 passed, 1 failed. Failed.

And when in verbose mode, we would have all the actions like done today.

What do you think?

Trouble resolving prereleases?

In https://github.com/cmeeren/fable-elmish-electron-material-ui-demo, I had installed a Feliz.MaterialUI version that had the following in its fsproj:

<NpmPackage Name="@material-ui/lab" Version="4.0.0-alpha.41" />

In the Electron project's package.json, the version was pinned to a lower one:

"@material-ui/lab": "4.0.0-alpha.32"

When I ran femto --resolve, it insisted that everything was OK, even though the package.json version was pinned to a lower version. I would expect femto to change it to

"@material-ui/lab": "4.0.0-alpha.41"

Make the return code reflect the global result

Hello @Zaid-Ajaj ,

great work and thank you for starting this tool that has been mentioned several times in the past :)

In general, a program return several "status code" which allow the caller to identify the final result.

So I propose something like:

  • 0 -> Everything is fine
  • 1 -> Missing package.json file Source
  • 2 -> Please install the project first Source
  • 3 -> One of the dependencies is not correct
    • Missing deps
    • Mismatch version

This is important especially when integrating the tool in a tool chain, this avoid the caller to parser the stdout text.

I can send a PR to the repo if the feature is accepted :)

How to support package with multiple way of installation?

If we take Font Awesome as an example, there are several ways to use that package.

  1. Use @fortawesome/fontawesome-free

  2. Use @fortawesome/fontawesome-svg-core and one of the svg package like @fortawesome/free-solid-svg-icons, @fortawesome/free-regular-svg-icons, etc.

Prevents crash of the program

While working Femto, it happened several time that I run it against an invalid fsproj or that I can't restore the project because I don't have the right version of dotnet installed.

In this case, Femto is crashing because I think ProjectCracker.fullCrack is throwing an exception that we don't cache.

I think we should wrap

let projectInfo = ProjectCracker.fullCrack project
let libraries = findLibraryWithNpmDeps projectInfo

in a try ... with ... block.

Or we could just wrap the entry point with try .... with ... and print the ex.Message and return FemtoResult.Crashed (a new entry to our FemtoResult enum) as a result.

Support source path with whitespace

My project path includes a space, causing femto to fail:

PS C:\Users\Firstname Lastname\spikes\project\src\client> dotnet femto install Feliz
[06:46:10 INF] Analyzing project C:\Users\Firstname Lastname\\spikes\project\src\client\Client.fsproj
[06:46:10 INF] Running dotnet restore against the project
[06:46:12 INF] Detected paket.references file -> use paket
[06:46:12 INF] Installing Feliz within dependency group Client
[06:46:12 INF] Using locally installed paket
[06:46:12 ERR] Error while running the following command:
[06:46:12 ERR] C:\Users\Firstname Lastname\spikes\project\src\client> dotnet paket add Feliz --project C:\Users\Firstname Lastname\spikes\project\src\client\Client.fsproj --group Client
[06:46:12 ERR] Process Output:
[06:46:12 ERR] Process Error: ... "dotnet-paket add Feliz --project C:\Users\Firstname" not found...

>= was escaped

Just want to let you know that VS seemed to auto-escape > in >= at one point, causing >= to become &gt;=. I think it happened when adding another file to the project.

Perhaps gt/gte/etc. should always be used, never >/>=/etc.?

Propose to run run yarn|npm install for the user

When detecting that the npm dependencies need to be restored, we could propose to the user to run yarn install or npm install for him.

This is similar to the behaviour introduce by webpack@4 where if they don't find webpack-cli they propose to run ti for you.

It would give something like that:

$ User launch Femto

> Npm packages need to be restored first
> Do you want Femto to run 'npm install' for you? (yes|no) // the command can be 'yarn install' if we detected 'yarn.lock'
> Yes
> Running 'yarn install'

$ Femto retries here

Check all projects in solution

It seems that currently, femto must be used for each project separately. It would be great if it could be used for all projects in a solution, and/or recursively for all projects in a subfolder.

Feature: Add "femto uninstall <package>"

Just like femto install <package>, calls either dotnet or paket to remove a package but without --resolve because we don't know which npm packages are used outside the project that removes the nuget package

femto upgrade

Would it make sense for there to be a femto upgrade that basically calls dotnet paket upgrade && yarn upgrade?

Using Femto as a library

This is an awesome tool! Thanks and congratulations to you both @Zaid-Ajaj and @MangelMaxime!

Did you get feedback about people using it? I'm assuming it's probably much easier for users if Femto is run automatically by Fable instead of adding an extra build step... Yes, I know I said I didn't want to add this kind of features to Fable, but if you maintain the tool and Fable just needs to call it, I'm happy with it ๐Ÿ˜‰

Would it be possible to also include the option of referencing and calling Femto as a library. Fable could call it after running dotnet restore and display warnings to the user if something is found.

Compatible issue with dotnet v3.0

Installed by issuing dotnet tool install femto --global and run femto but the error pops up:

It was not possible to find any compatible framework version
The specified framework 'Microsoft.NETCore.App', version '2.2.0' was not found.
  - The following frameworks were found:
      3.0.0 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Env:

CentOS 7 x64
dotnet core 3.0.100
fable-compiler 2.4.6
node.js v10

Resolution project from current directory is broken

When adding Argu, I made a regression.

We are forced to pass the project path.

Executing this command dotnet ../../../../Zaid-Ajaj/Femto/bin/Debug/netcoreapp2.2/Femto.dll print the manual instead of running Femto using the current directory.

Cannot use global paket?

Tried to use Femto with the SAFE stack template out of the box and ran into:

ฮป femto install Feliz
[15:04:38 INF] Analyzing project C:\Development\Informedica\apps\GenPed\src\Client\Client.fsproj
[15:04:38 INF] Running dotnet restore against the project
[15:04:39 INF] Detected paket.references file -> use paket
[15:04:39 INF] Installing Feliz within dependency group Client
[15:04:39 INF] Using locally installed paket
[15:04:39 ERR] Error while running the following command:
[15:04:39 ERR] C:\Development\Informedica\apps\GenPed\src\Client> dotnet paket add Feliz --project C:\Development\Informedica\apps\GenPed\src\Client\Client.fsproj --group Client
[15:04:39 ERR] Process Output:
[15:04:39 ERR] Process Error: Could not execute because the specified command or file was not found.
Possible reasons for this include:

  • You misspelled a built-in dotnet command.
  • You intended to execute a .NET Core program, but dotnet-paket add Feliz --project C:\Development\Informedica\apps\GenPed\src\Client\Client.fsproj does not exist.
  • You intended to run a global tool, but a dotnet-prefixed executable with this name could not be found on the PATH.

/c/Development/Informedica/apps/GenPed/src/Client
ฮป paket
Paket version 5.242.1

So, paket is installed as a global tool. When adding paket.exe locally to the .paket folder, it works like a charm.

My local windows 10 dotnet specs:

.NET Core SDK (reflecting any global.json):
Version: 3.0.100
Commit: 04339c3a26

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18362
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100\

Host (useful for support):
Version: 3.0.0
Commit: 7d57652f33

.NET Core SDKs installed:
2.1.801 [C:\Program Files\dotnet\sdk]
2.1.802 [C:\Program Files\dotnet\sdk]
2.2.401 [C:\Program Files\dotnet\sdk]
2.2.402 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

--resolve doesn't install multiple packages

Running femto --resolve only resolves one package even though the install expression consists of multiple packages that are separated a space (maybe CreateProcess splits again by space?)

Add option --json for machine-readable output

Running

femto --json
# or
femto --project ./src/App.fsproj --json

Generates JSON report output about the npm dependencies required or missing, I need to think about what exactly is needed and how this JSON should look like. @MangelMaxime Do you have a suggestion?

I was thinking about something like:

{
  "projects": [ 
     { 
        "name": "Fable.DateFunction", 
        "dependencies": [  
            {   
                 "name": "date-fns", 
                 "resolutionStrategy": "min",
                 "required": ">= 1.30.0", 
                 "resolved": "1.30.1",
                 "installed": "1.29.0" ,
                 "packageJsonRange": "^1.28.2",
                 "missing": false
             } 
          ]
      }
   ]
}

Remove InstallHint property

If I understand correctly the README, the hint is "static" and is determined using InstallHint="npm install [email protected]"

I think we could remove the InstallHint parameter because we already have all the infos needed to generate it.

  1. Detect if the project is using yarn or npm. If the repo contains a yarn.lock then it's using yarn
  2. Extract the version from >= 1.30.0
  3. Generates {Command} install {Package}@{Version}

Funny business occur when validating a non-existing package

Femto shows the help guide ๐Ÿ˜… if you validate a project that has a npm package that does not exist:

<NpmDependencies>
    <NpmPackage Name="mssql" Version=">= 5.1.0" />
    <NpmPackage Name="does-not-really-exist" Version=">= 6.2.0" />
</NpmDependencies>

now validating the project gives logs

c:\projects\Fable.SqlClient>femto ./src --validate
[10:42:31 INF] Validating project c:/projects/Fable.SqlClient/src/Fable.SqlClient.fsproj
[10:42:31 INF] Running dotnet restore against the project
[10:42:32 INF] Ensuring project can be analyzed
[10:42:36 INF] Fable.SqlClient requires npm package mssql
[10:42:36 INF]   | -- Required range >= 5.1.0
[10:42:36 INF]   | -- Resolution strategy 'Min'
[10:42:38 INF]   | -- โˆš Found version 5.1.0 that satisfies the required range
[10:42:38 INF] Fable.SqlClient requires npm package does-not-really-exist
[10:42:38 INF]   | -- Required range >= 6.2.0
[10:42:38 INF]   | -- Resolution strategy 'Min'
USAGE: femto [--help] [--validate] [--resolve] [--version] [<path>]

PROJECT:

    <path>                specify the path to the F# project.

OPTIONS:

    --validate            check that the XML tags used in the F# project file are parsable and a npm package
                          version can be calculated.
    --resolve             resolve and install required packages.
    --version             display the current version of Femto.
    --help                display this list of options.


c:\projects\Fable.SqlClient> 

cc @MangelMaxime

Femto validate is not consistent

femto validate seems to looks for a package.json while it's not needed and this also result in a different output between a repo with or without package.json .

With package.json

โžœ  fable-react git:(remove_react_dom) femto validate ./src/Fable.React.fsproj 
[11:35:13 INF] Analyzing project /Users/maximemangel/Workspaces/Github/fable-compiler/fable-react/src/Fable.React.fsproj
[11:35:16 INF] Found package.json in /Users/maximemangel/Workspaces/Github/fable-compiler/fable-react
[11:35:16 INF] Using npm for package management
[11:35:17 INF] Fable.React requires npm package react
[11:35:17 INF]   | -- Required range >= 16.8.0 found in project file
[11:35:17 INF]   | -- Missing react in package.json
[11:35:17 INF]   | -- Resolve manually using 'npm install [email protected] --save

Without package.json

[11:36:22 INF] Analyzing project /Users/maximemangel/Workspaces/Github/elmish/react/src/Fable.Elmish.React.fsproj
[11:36:24 INF] Fable.React requires npm package react (>= 16.8.0)
[11:36:24 INF] Fable.React.Dom requires npm package react-dom (>= 16.8.0)
[11:36:24 WRN] Could not locate package.json file

femto validate should not try to look for package.json and neither restore the package.json.

If should just run npm show <package> versions --json directly and output the compact logs with a global result valid/not valid.

I am pretty sure, I had the global result implemented, I think we made a regression.

Add option --preview-metadata for library authors

Add option --preview-metadata is for library authors to check that the XML tags used in the F# project file is actually parsable and a npm package version can be calculated .

Example usage

cd MyAwesomeLibrary
cd src
femto --preview-metadata

Femto v0.5.2 getPackageVersions fails when using yarn v1.16.0

Running femto or femto --resolve doesn't seem to work with yarn as of latest version of Femto 0.5.2, the function getPackageVersions fails retrieving the package information.

The problem can be reproduced by starting from a fresh SAFE template, adding a package with Femo-compatible metadata (Elmish.SweetAlert, Feliz etc.) and running femto against the Client project.

@MangelMaxime can you please confirm whether such problem occurs with you as well? I have yarn 1.16.0 installed

Remove or normalize "@" usage when logging the preview

When previewing the action the output looks like:

[16:57:56 INF] NpmPackageNotInstalled -> Uninstall bulma @ 0.6.0
[16:57:56 INF] NpmPackageNotInstalled -> Install bulma @ 0.7.0

I would prefer to generate:

[16:57:56 INF] NpmPackageNotInstalled -> Uninstall bulma version 0.6.0
[16:57:56 INF] NpmPackageNotInstalled -> Install bulma version 0.7.0

but if we keep the @ symbol I would prefer to "normalize" the usage by removing the spaces around it.

What do you think?

Add option --resolve: automatically install required packages

Now with ability to calculate which packages we need to install, we can combine the packages into a single command and install all the packages needed for the user.

Example usage:

# current directory
femto --auto-resolve

# specify path
femto --auto-resolve ./src/Client.fsproj

# specify path 2
femto --auto-resolve --project ./src/Client.fsproj

Femto force user to explictly install a dependencies and not have it as transitive (from npm POV)

I am working on binding express which have a bunch of API coming from other packages.

For example, it use mime package. I did bind the Mime API but now I am unsure if I want to add the femto properties in it.

In general, we just do npm i express but if I add the femto properties it will ask the user to install it manually in the package.json and not have it as a transitive dependencies.

Is this behaviour ok?

I am asking because in the end the user will probably have to install all the dependencies of express in it package.json which is not standard.

Should we find a way to say, Mime binding is included by Express bindings and so should not be explicitly required?

Detect if the package should be installed as a deps or dev deps

When uninstalling and installing a package because of a mismatched version we should detect if the package was a deps or dev deps to reinstall it correctly.

We could also ask how to install each deps on having the list using an interactive mode but that less of a problem that the first scenario.

Unify resolve preview and project analysis logs

By @MangelMaxime in this comment here

I asked my self this question in the past and yes they look similar but have small differences.
--preview will fail is not package.json has been found.
While --validate can be used even if no package.json is present.
And --preview show what actions will be applied to the project. It will tell you that it will uninstall that version of the library and install this one.
However, I do think that running femto without arguments is a duplicate of one of the feature we have.

I think --preview and running without args should be the same and output the "nicely formatted" logs.

That's what I am thinking of too, not providing any arguments (except project file or path) should be an alias for --preview and --preview logs can be more nicely formatted

[Feature] Introduce one "install" command to rule them all

Introduce install command that unifies package installation between nuget and paket, then executes --resolve afterwards to install potentially required npm packages.

Workflow of femto install <package>

1 - Paket

Detect paket usage by checking the existence of paket.references file. if the file exists then check which dependency group should be used by parsing the first line of the of paket.references and extracting the used group from it, if no dependency group is used, then use Main as the default group. femto install <package> will then compute and execute the paket command

paket add <package> --group <deletected-group> --project <femto-input-project>

2 - Nuget

if no paket.references is found, then femto install <package> will issue the command dotnet add package <package> and resolve required dependencies afterwards

Propagate the use of --version

The command femto install <package> --version <version> propagates the --version <version> parameter to both the paket and nuget install commands

Proposal: install paket if it is not installed or tell the user to install it?

Detect whether paket is installed using paket --version and install it using dotnet tool install paket -g or just show an error message to the user telling him or her that they should install paket and giving them the required download link or download commands.

@MangelMaxime @alfonsogarciacaro What do you guys think?

Transitive dependencies

Alright Fable.DateFunctions is now published to nuget with npm dependency metadata. You take it for a spin to test things out.

Another thing I want to test is transitive dependencies:

Say I have project called App and I install Fable.Elmish.React then if I run Femto against App it should pick up react >= 16.8.0 and react-dom >= 16.8.0 from Fable.React (assuming we add the metadata of these npm dependencies to Fable.React)

Originally posted by @Zaid-Ajaj in #8 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.