this is the WIP of the PR fsprojects/Paket#2938
- Why
- Comparison with existing similar
- How works
- Examples
- KNOWN BUGS or NOT IMPLEMENTED YET
- How works - more info
We need console app (tools from now on) for lots of reason in development.
Some are helpers for dev (dotnet-watch
, serve
, forge
, ildasm
).
Some are needed by build (nunit-console
, ilrepack
) or for both (fake
, dotnet-fable
, dotnet-xunit
)
While the former (dev tools) MAY not need to be versioned with codebase, the latter (for build, for both) should be to make build reproducible.
Tools should be easy to install, nice developer UX from cli, easy runnable from shell scripts, multi os and runtimes, versioned with repo (if needed), can be invoked by any third party tooling.
Repo tools features:
- discovery and install from nupkg, written in
paket.dependencies
asrepotool MyTool
- are versioned in repository. usual
paket.lock
benefits, like reproducible build- no global install or per machine or per user. per repository
- fixed install location for easier build orchestration
- works multi os (unix/win/mac)
- works in win+WSL. no need to redo restore, both scripts for win and linux exists and wors
- tools can be targeting .net and/or .net core (multiple fw supported in same nupkg)
- helper scripts for dev flow
- user can choose the preferred .net runtime use for tools
- compatibile with old nupkg with .net exe in
tools
directory
The repo tools are declared in the paket.dependencies
as repotool
, like
repotool myhello 0.4.0
These works like normal nupkg for resolution, but are standalone and doesnt contribute to project references. Can be used without project files too.
The version resolved by paket install
will be locked (as usual) in paket.lock
, and that specific version will be used (as usual) by paket restore
SPEC:
- A nupkg who is a repo tools, just need to add published console apps in
tools
directory based on runtime. - can support multiple runtimes in same nupkg
- .net framework console app (require .NET Framework or
mono
installed) - .net core console app published as FDD (require .net core runtime installed)
- .net framework console app (require .NET Framework or
- in future, a config file will optionally allow to specify more settings, atm is by convention
PAKET:
- will install and restore the package as usual
- will create the shell scripts for invocation (both windows batch and unix/mac shell script) in
paket-files/bin
dir - will create an helper script
paket-files/bin/add_to_PATH
to improve dev UX
See also How works - more info
Type | .NET | .NET Core | Run in any dir | Per user (global) | Per repo | Per .csprj/.fsproj | Xplat CLI |
---|---|---|---|---|---|---|---|
Repo tools | X | X | X | X | X | ||
Dotnet cli tool | X | X | X | ||||
Dotnet cli global tools | X | X | X | X | |||
console in tools dir of nupkg | X | X | X |
NOTE Dotnet cli global tools are wip in .net core sdk v2.1 so may change, more info here Repo tools will allow to consume these packages too
NOTE The dotnet cli tool require the working directory to be the same of the project where is specified (the .csproj/.fsproj)
NOTE the Xplat CLI
mean the same invocation string can be used for all os in shell (no need to think about mono on osx/unix for example)
NOTE Each example assume a clean repo, so feel free to git clean -xdf
at start of each example
Examples use windows dir separator, sry, but fixing that should works on unix or windows WSL
.paket\paket install
that will:
- create the dir
paket-files\paket\bin
with the shell scripts - lock the repo tools in the
paket.lock
likemyhello (0.4.0) - repotool: true
Is possible to run installed commands, like
paket-files\bin\FAKE --version
paket-files\bin\hello 1 2 3
paket-files\bin\myhello a b c
do .paket\paket install
, remove the paket-files
directory, but leave paket.lock
now run .paket\paket restore
same as example 1
paket-files\bin\myhello a b c
A repo tools can support multiple runtime. so both .net core and .net.
by default, the preferred runtime is the one of paket executable (atm is .net)
but can be configured unsing PAKET_REPOTOOL_PREFERRED_RUNTIME
env var
valid values: net
/netcoreapp
set the env var:
set PAKET_REPOTOOL_PREFERRED_RUNTIME=netcoreapp
now let's install
.paket\paket install
and run a .net core tool, like the .net version
paket-files\bin\myhello
in the example, the myhello
tool will now use .net core.
if you cat the paket-files\bin\myhello.cmd
will be:
dotnet "%~dp0..\..\packages\myhello\tools\netcoreapp2.0\myhello.dll" %*
btw normally (the default is .NET) is:
"%~dp0..\..\packages\myhello\tools\net45\myhello.exe" %*
Same for the .sh
NOTE the hello
, contained in RepoTool.Sample
nupkg, doesnt have same name of pkg
NOTE run as dotnet
will respect the global.json
file, if exist
.paket\paket install
now add the paket-files\bin
to PATH
set PATH=%CD%\paket-files\bin;%PATH%
and run the commands
FAKE --version
fsc --help
fsi --help
The working directory doesnt matter anymore
mkdir prova
cd prova
myhello
and where fsi
(or which fsi
)
manually change the PATH
is annoying and error prone.
after install/restore, paket generate an helper script (two, by os)
- in windows command prompt:
paket-files\bin\add_to_PATH
- in unix shell:
source paket-files/bin/add_to_PATH.sh
this will just add the paket-files/bin
dir as prefix in PATH
env var for current session
so now
FAKE --version
fsc --help
fsi --help
works, same as example 4
a scenario good to later set FscToolPath
/FscToolExe
to configure the msbuild compilation
Like the paket add
command who add nupkg, the add-tool
command:
- add tools in
paket.dependencies
- resolve, restore and install it
usual flags to configure behavior (--no-install
,etc)
.paket\paket add-tool NUnit.ConsoleRunner
After that
paket-files\bin\nunit3-console --version
both paket.dependencies
and paket.lock
are updated with that tool
the [X] are fixed
- chmod+x for shell scripts
- warning if the prefferred runtime is not supported on restore by a tool
- powershell helper script to change
$env:PATH
- discover .net core tools based on
mytool.deps.json
file search the nupkg for tool atno need, assume strategy is stable.install
step, write relative path found inpaket.lock
. atrestore
step, just write down the wrappers- shell scripts don't work on git-bash on windows, because try to run mono. check
ComSpec
env var if is win (ref so) - using
storage:none
and proj in another drive, the shell script are wrong in WLS -
paket add-tool FSharp.Compiler.Tools
(likeadd
command) to add asrepotool
in deps, and install it now
- use native wrappers instead of shell scripts
paket run mytool
(npm-like) orpaket mytool
(dotnetcli like) orpaket exec mytool
(bundler like) who will just invokepaket-files\bin\mytool
. ask to install if not already installed- kill the child tool it if parent process (the script) is termined
- discover .net core tools based on PE header magic string
- configure alias, especially for .net core tools.
- support configuration of alias as metadata of the package, so pkg authors can do that
- support native binaries, or .net with a target os/runtimes (for native dll)
- support native binaries splitted in multiple packages (runtimes.json in nupkg?) to minimize donwload size at restore
idea is to have wrapper script in a fixed location to invoke a tool (but each tool can use a different runtime or be in different install location) the preferred runtime to use is not locked
- paket install/restore the nupkg as usual (settings for nupkg like storage:none/groups/source/etc apply too)
- paket after downloading the nupkg (on restore/install) will create some shell scripts to invoke these
- the shell script, in
paket-files/bin
can be invoked aspaket-files/bin/mytool
:- for win is
mytool.cmd
a normal batch script - for osx/linux is
mytool
a normal shell script
- for win is
- the shell script will invoke:
- for .net fw console app:
mono mytool.exe
on osx/unix, directlymytool.exe
on win - for .net core console app:
dotnet mytool.dll
- for .net fw console app:
- doesnt matter where the packages are restored, if in
packages
dir or instorage:none
(user nuget cache dir). - normally is enough
paket-files/bin/mytool
(with right dir separator) in both windows/unix, if run as shell command - adding
paket-files\bin
toPATH
, the commands can be run asmytool
directly (withoutpaket-files/bin
full path) - paket will create a helper script to help modify the
PATH
env var:- for win:
paket-files\bin\add_to_PATH
- for unix:
source paket-files/bin/add_to_PATH.sh
- for win:
Just .NET Framework and .NET Core console app are supported (atm)
- any
tools/*.exe
is considered a .NET Framework console app.- see
FAKE
nupkg as example (useful for old tools)
- see
- any
tools/net{version}/*.exe
is considered a .NET Framework console app.- see
RepoTool.Sample
nupkg as example
- see
- any
tools/netcoreapp{version}/{pkgName}.dll
is considered a .NET Core console app.- see
myhello
nupkg as example - the console app must be an FDD, so require .net core runtime installed
- see
- any
tools/netcoreapp{version}/{name}.dll
with a{name}.deps.json
is considered a .NET Core console app.- see
RepoTool.Sample
nupkg as example (pkg name isRepoTool.Sample
but exe ishello
) - the console app must be an FDD, so require .net core runtime installed
- see
paket after install
or restore
will create some shell script in paket-files\bin
to invoke these tools