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

Add support for dotnet local tools #2399

Merged
merged 24 commits into from
Oct 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5eb6251
Provide a more general mechanism for substituting a dotnet tool for a…
SteveGilham Sep 29, 2019
7ef4c24
Sketch the "withDotNet" approach, pivoting to Fake.DotNet.Cli.
SteveGilham Oct 6, 2019
130587e
Bring the full functionality of `DotNet.exec` into play
SteveGilham Oct 15, 2019
ffe3369
Merge remote-tracking branch 'upstream/release/next' into develop/iss…
SteveGilham Oct 15, 2019
225b9b5
Use DotNet ToolType for Paket
Tarmil Oct 17, 2019
e675756
Merge remote-tracking branch 'Tarmil/FAKE/issue-2398' into develop/is…
SteveGilham Oct 18, 2019
ebac051
Fix legacy build
SteveGilham Oct 18, 2019
832bbb4
Make the new functions and types part of the Fake.DotNet namespace
SteveGilham Oct 19, 2019
36d4be4
Redesign some internals to make the Dotnet Tool stuff similar to 'wit…
matthid Oct 19, 2019
49c3804
Merge branch 'develop/issue-2398' of https://github.com/SteveGilham/F…
matthid Oct 19, 2019
9c13b4e
Merge pull request #1 from fsharp/SteveGilham-develop/issue-2398
SteveGilham Oct 19, 2019
a2df6ec
Add some docs to explain the situation
matthid Oct 19, 2019
7dc76d2
Merge branch 'release/next' of github.com:fsharp/FAKE into SteveGilha…
matthid Oct 19, 2019
05d9d6a
This should work for all tools and modes, fix tests
matthid Oct 19, 2019
b400a93
Add some docs for the new concept
matthid Oct 19, 2019
c7eb52d
add redirect if not redirected function, but add a warning
matthid Oct 19, 2019
f34a8ed
Restore original trace behaviour
SteveGilham Oct 20, 2019
d9cd497
Try to fix failing tests by waiting for output to be read completely.
matthid Oct 20, 2019
0b364a0
Merge branch 'develop/issue-2398' of https://github.com/SteveGilham/F…
matthid Oct 20, 2019
1f31618
use sh on non-windows.
matthid Oct 20, 2019
79e35e8
fix escaping
matthid Oct 20, 2019
6d69f6d
Add more options to debug #2401
matthid Oct 20, 2019
a8c20e0
add docs around local tools
matthid Oct 20, 2019
9337b69
fix build and update release notes
matthid Oct 20, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 60 additions & 40 deletions .paket/Paket.Restore.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>

<DetectedMSBuildVersion>$(MSBuildVersion)</DetectedMSBuildVersion>
<DetectedMSBuildVersion Condition="$(MSBuildVersion) == ''">15.0.0</DetectedMSBuildVersion>
<DetectedMSBuildVersion Condition="'$(MSBuildVersion)' == ''">15.0.0</DetectedMSBuildVersion>
<MSBuildSupportsHashing>false</MSBuildSupportsHashing>
<MSBuildSupportsHashing Condition=" '$(DetectedMSBuildVersion)' &gt; '15.8.0' ">true</MSBuildSupportsHashing>
<!-- Mark that this target file has been loaded. -->
Expand All @@ -27,44 +27,13 @@
<PaketBootStrapperExePath Condition=" '$(PaketBootStrapperExePath)' == '' AND Exists('$(PaketRootPath)paket.bootstrapper.exe')">$(PaketRootPath)paket.bootstrapper.exe</PaketBootStrapperExePath>
<PaketBootStrapperExePath Condition=" '$(PaketBootStrapperExePath)' == '' ">$(PaketToolsPath)paket.bootstrapper.exe</PaketBootStrapperExePath>
<PaketBootStrapperExeDir Condition=" Exists('$(PaketBootStrapperExePath)') " >$([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\</PaketBootStrapperExeDir>

<!-- Paket -->

<!-- windows, root => tool => proj style => bootstrapper => global -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND Exists('$(PaketRootPath)paket.exe') ">$(PaketRootPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND Exists('$(PaketToolsPath)paket.exe') ">$(PaketToolsPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND '$(PaketBootstrapperStyle)' == 'proj' ">$(PaketToolsPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND Exists('$(PaketBootStrapperExeDir)') ">$(_PaketBootStrapperExeDir)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' ">paket.exe</PaketExePath>

<!-- no windows, try native paket as default, root => tool => proj style => mono paket => bootstrpper => global -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketRootPath)paket') ">$(PaketRootPath)paket</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketToolsPath)paket') ">$(PaketToolsPath)paket</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND '$(PaketBootstrapperStyle)' == 'proj' ">$(PaketToolsPath)paket</PaketExePath>

<!-- no windows, try mono paket -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketRootPath)paket.exe') ">$(PaketRootPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketToolsPath)paket.exe') ">$(PaketToolsPath)paket.exe</PaketExePath>

<!-- no windows, try bootstrapper -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketBootStrapperExeDir)') ">$(PaketBootStrapperExeDir)paket.exe</PaketExePath>

<!-- no windows, try global native paket -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' ">paket</PaketExePath>

<!-- Paket command -->
<_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))</_PaketExeExtension>
<PaketCommand Condition=" '$(PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)"</PaketCommand>
<PaketCommand Condition=" '$(PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"</PaketCommand>
<PaketCommand Condition=" '$(PaketCommand)' == '' ">"$(PaketExePath)"</PaketCommand>



<PaketBootStrapperCommand Condition=" '$(OS)' == 'Windows_NT'">"$(PaketBootStrapperExePath)"</PaketBootStrapperCommand>
<PaketBootStrapperCommand Condition=" '$(OS)' != 'Windows_NT' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"</PaketBootStrapperCommand>

<!-- Disable automagic references for F# dotnet sdk -->
<!-- This will not do anything for other project types -->
<!-- see https://github.com/fsharp/fslang-design/blob/master/RFCs/FS-1032-fsharp-in-dotnet-sdk.md -->
<!-- see https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1002-fsharp-in-dotnet-sdk.md -->
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>

Expand All @@ -74,14 +43,65 @@
<PaketIntermediateOutputPath Condition=" '$(PaketIntermediateOutputPath)' == '' ">$(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/'))</PaketIntermediateOutputPath>
</PropertyGroup>

<!-- Check if paket is available as local dotnet cli tool -->
<Target Name="SetPaketCommand" >

<!-- Call 'dotnet paket' and see if it returns without an error. Mute all the output. -->
<Exec Command="dotnet paket --version" IgnoreExitCode="true" StandardOutputImportance="low" StandardErrorImportance="low" >
<Output TaskParameter="ExitCode" PropertyName="LocalPaketToolExitCode" />
</Exec>

<!-- If local paket tool is found, use that -->
<PropertyGroup Condition=" '$(LocalPaketToolExitCode)' == '0' ">
<InternalPaketCommand>dotnet paket</InternalPaketCommand>
</PropertyGroup>

<!-- If not, then we go through our normal steps of setting the Paket command. -->
<PropertyGroup Condition=" '$(LocalPaketToolExitCode)' != '0' ">
<!-- windows, root => tool => proj style => bootstrapper => global -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND Exists('$(PaketRootPath)paket.exe') ">$(PaketRootPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND Exists('$(PaketToolsPath)paket.exe') ">$(PaketToolsPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND '$(PaketBootstrapperStyle)' == 'proj' ">$(PaketToolsPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' AND Exists('$(PaketBootStrapperExeDir)') ">$(_PaketBootStrapperExeDir)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' == 'Windows_NT' ">paket.exe</PaketExePath>

<!-- no windows, try native paket as default, root => tool => proj style => mono paket => bootstrpper => global -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketRootPath)paket') ">$(PaketRootPath)paket</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketToolsPath)paket') ">$(PaketToolsPath)paket</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND '$(PaketBootstrapperStyle)' == 'proj' ">$(PaketToolsPath)paket</PaketExePath>

<!-- no windows, try mono paket -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketRootPath)paket.exe') ">$(PaketRootPath)paket.exe</PaketExePath>
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketToolsPath)paket.exe') ">$(PaketToolsPath)paket.exe</PaketExePath>

<!-- no windows, try bootstrapper -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' AND Exists('$(PaketBootStrapperExeDir)') ">$(PaketBootStrapperExeDir)paket.exe</PaketExePath>

<!-- no windows, try global native paket -->
<PaketExePath Condition=" '$(PaketExePath)' == '' AND '$(OS)' != 'Windows_NT' ">paket</PaketExePath>

<_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))</_PaketExeExtension>
<InternalPaketCommand Condition=" '$(InternalPaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)"</InternalPaketCommand>
<InternalPaketCommand Condition=" '$(InternalPaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"</InternalPaketCommand>
<InternalPaketCommand Condition=" '$(InternalPaketCommand)' == '' ">"$(PaketExePath)"</InternalPaketCommand>

</PropertyGroup>

<!-- The way to get a property to be available outside the target is to use this task. -->
<CreateProperty Value="$(InternalPaketCommand)">
<Output TaskParameter="Value" PropertyName="PaketCommand"/>
</CreateProperty>

</Target>

<Target Name="PaketBootstrapping" Condition="Exists('$(PaketToolsPath)paket.bootstrapper.proj')">
<MSBuild Projects="$(PaketToolsPath)paket.bootstrapper.proj" Targets="Restore" />
</Target>

<!-- Official workaround for https://docs.microsoft.com/en-us/visualstudio/msbuild/getfilehash-task?view=vs-2019 -->
<UsingTask TaskName="Microsoft.Build.Tasks.GetFileHash" AssemblyName="Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Condition=" '$(MSBuildSupportsHashing)' == 'true' And '$(DetectedMSBuildVersion)' &lt; '16.0.360' " />
<UsingTask TaskName="Microsoft.Build.Tasks.VerifyFileHash" AssemblyName="Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Condition=" '$(MSBuildSupportsHashing)' == 'true' And '$(DetectedMSBuildVersion)' &lt; '16.0.360' " />
<Target Name="PaketRestore" Condition="'$(PaketRestoreDisabled)' != 'True'" BeforeTargets="_GenerateDotnetCliToolReferenceSpecs;_GenerateProjectRestoreGraphPerFramework;_GenerateRestoreGraphWalkPerFramework;CollectPackageReferences" DependsOnTargets="PaketBootstrapping">
<Target Name="PaketRestore" Condition="'$(PaketRestoreDisabled)' != 'True'" BeforeTargets="_GenerateDotnetCliToolReferenceSpecs;_GenerateProjectRestoreGraphPerFramework;_GenerateRestoreGraphWalkPerFramework;CollectPackageReferences" DependsOnTargets="SetPaketCommand;PaketBootstrapping">

<!-- Step 1 Check if lockfile is properly restored (if the hash of the lockfile and the cache-file match) -->
<PropertyGroup>
Expand Down Expand Up @@ -116,7 +136,7 @@
</PropertyGroup>

<PropertyGroup Condition=" '$(MSBuildSupportsHashing)' == 'true' And '$(CacheFilesExist)' == 'true' ">
<!-- If the restire file doesn't exist we need to restore, otherwise only if hashes don't match -->
<!-- If the restore file doesn't exist we need to restore, otherwise only if hashes don't match -->
<PaketRestoreRequired>true</PaketRestoreRequired>
<PaketRestoreRequired Condition=" '$(PaketRestoreLockFileHash)' == '$(ProjectsRestoredHash)' ">false</PaketRestoreRequired>
<PaketRestoreRequired Condition=" '$(PaketRestoreLockFileHash)' == '' ">true</PaketRestoreRequired>
Expand Down Expand Up @@ -203,7 +223,7 @@
<PackageName>$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])</PackageName>
<PackageVersion>$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])</PackageVersion>
<AllPrivateAssets>$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])</AllPrivateAssets>
<CopyLocal Condition="'$(Splits)' == '6'">$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])</CopyLocal>
<CopyLocal Condition="'%(PaketReferencesFileLinesInfo.Splits)' == '6'">$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])</CopyLocal>
</PaketReferencesFileLinesInfo>
<PackageReference Include="%(PaketReferencesFileLinesInfo.PackageName)">
<Version>%(PaketReferencesFileLinesInfo.PackageVersion)</Version>
Expand Down Expand Up @@ -246,7 +266,7 @@
</PropertyGroup>
</Target>

<Target Name="PaketOverrideNuspec" AfterTargets="GenerateNuspec" Condition="('$(IsPackable)' == '' Or '$(IsPackable)' == 'true') And Exists('$(PaketIntermediateOutputPath)/$(MSBuildProjectFile).references')" >
<Target Name="PaketOverrideNuspec" DependsOnTargets="SetPaketCommand" AfterTargets="GenerateNuspec" Condition="('$(IsPackable)' == '' Or '$(IsPackable)' == 'true') And Exists('$(PaketIntermediateOutputPath)/$(MSBuildProjectFile).references')" >
<ItemGroup>
<_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/>
<MSBuildMajorVersion Include="$(DetectedMSBuildVersion.Replace(`-`, `.`).Split(`.`)[0])" />
Expand Down Expand Up @@ -300,7 +320,7 @@
DevelopmentDependency="$(DevelopmentDependency)"
BuildOutputInPackage="@(_BuildOutputInPackage)"
TargetPathsToSymbols="@(_TargetPathsToSymbols)"
SymbolPackageFormat="symbols.nupkg"
SymbolPackageFormat="$(SymbolPackageFormat)"
TargetFrameworks="@(_TargetFrameworks)"
AssemblyName="$(AssemblyName)"
PackageOutputPath="$(PackageOutputAbsolutePath)"
Expand Down Expand Up @@ -347,7 +367,7 @@
DevelopmentDependency="$(DevelopmentDependency)"
BuildOutputInPackage="@(_BuildOutputInPackage)"
TargetPathsToSymbols="@(_TargetPathsToSymbols)"
SymbolPackageFormat="symbols.nupkg"
SymbolPackageFormat="$(SymbolPackageFormat)"
TargetFrameworks="@(_TargetFrameworks)"
AssemblyName="$(AssemblyName)"
PackageOutputPath="$(PackageOutputAbsolutePath)"
Expand Down
9 changes: 6 additions & 3 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Release Notes

## 5.17.1-alpha - tbd
## 5.18.0-alpha - 2019-10-21

* tbd
* ENHANCEMENT: Add core support for local tools via `CreateProcess.withToolType`, this helper is part of `Fake.DotNet.Cli` and available after `open Fake.Core` - https://github.com/fsharp/FAKE/pull/2399
* ENHANCEMENT: Add `ToolType` support in `ReportGenerator` and `Paket`, thanks @SteveGilham and @Tarmil - https://github.com/fsharp/FAKE/pull/2399
* ENHANCEMENT: Add `FAKE_COREFX_VERBOSE` in order to increase verbosity for the FAKE libraries
* BUGFIX: Address https://github.com/fsharp/FAKE/issues/2406 by only printing a warning instead of crashing
* BUGFIX: Partially address https://github.com/fsharp/FAKE/issues/2401 by allowing the user to continue and request additional info.

## 5.17.0 - 2019-10-10

Expand All @@ -29,7 +33,6 @@
* ENHANCEMENT: Added `ProcessUtils.tryFindLocalTool` to resolve tools via a common logic (`Fake.IO.Globbing.Tools` is now obsolete)
* DOCS: Fix some broken links - https://github.com/fsharp/FAKE/issues/2351


## 5.16.0 - 2019-08-17

* LEGACY: Remove `Fake.Deploy` from repository and NuGet package, see https://github.com/fsharp/FAKE/issues/1820
Expand Down
39 changes: 39 additions & 0 deletions help/markdown/dotnet-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ open Fake.DotNet
// Lazily install DotNet SDK in the correct version if not available
let install = lazy DotNet.install DotNet.Versions.Release_2_1_4

// Alternative: Read from global json
let install = lazy DotNet.install DotNet.Versions.FromGlobalJson

// Define general properties across various commands (with arguments)
let inline withWorkDir wd =
DotNet.Options.lift install.Value
Expand Down Expand Up @@ -42,3 +45,39 @@ DotNet.restore (fun args ->
```

More [API Documentation](apidocs/v5/fake-dotnet-dotnet.html)

## SDK tools (local, global, clireference)

Some dotnet SDK based tools support project or path based installation. These tools have a `ToolType` parameter in addition to the `ToolPath` or `ExePath` parameters.

> Note: If your tool doesn't have this parameter please send a pull request to add it. See the [`ReportGenerator.fs` file changes in PR 2399](https://github.com/fsharp/FAKE/pull/2399/files#diff-6bd782ab06dfa727e4e35ce4bbaae43c) on an example what needs to be changed. Basically `CreateProcess.withFramework` is replaced with `CreateProcess.withToolType`.

You can use the parameter similar to this (in this example to start the reportgenerator as local tool with `dotnet reportgenerator`):

```fsharp
let install = lazy DotNet.install DotNet.Versions.FromGlobalJson
Target.create "Generate Reports" (fun _ ->
let parameters p = { p with ToolType = ToolType.CreateLocalTool(install.Value) }
!! "**/opencover.xml"
|> ReportGenerator.generateReports parameters
)
```

Here are the possible options:

- `ToolType.CreateFullFramework()`: Start as dotnet global tool (`<tool>.exe`, `mono` prefix on unix). This is the default and how fake behaved historically for most tools.
- `ToolType.CreateFrameworkDependentDeployment(install.Value)`: Start as framework dependendt deployment (`dotnet <tool>.dll`, no `mono` prefix on unix)
- `ToolType.CreateGlobalTool()`: Start as dotnet global tool (`<tool>.exe`, no `mono` prefix on unix)
- `ToolType.CreateLocalTool(install.Value)`: Start as dotnet local tool (`dotnet <tool>`)
- `ToolType.CreateCLIToolReference(install.Value)`: Start as dotnet cli tool reference (`dotnet <tool>`)

To set a different tool command (first argument of `dotnet`) `DotNet.Option`, for example because you use your own package with a different tool name. You can use:

```fsharp
{ p with
ToolType =
ToolType.CreateLocalTool(install.Value)
|> ToolType.withDefaultToolCommandName "alternative" }
```

This will call `dotnet alternative <arguments>`
18 changes: 16 additions & 2 deletions help/markdown/fake-gettingstarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ FAKE is completely written in F# and all build scripts will also be written in F

There are various ways to install FAKE 5:

* Install FAKE as a local `dotnet tool` (easiest, but needs [.NET Core SDK Version 3 or newer](https://dotnet.microsoft.com/download)):
* First you need to create a [tool manifest](https://medium.com/@bilalfazlani/net-core-local-tools-are-here-fe9ac2464481), which should be commited to your repository:
<pre><code class="lang-bash">
dotnet new tool-manifest
</code></pre>
* To install FAKE, run:
<pre><code class="lang-bash">
dotnet tool install fake-cli
</code></pre>

Use `--version` to specify the version of FAKE. See the [`local_tool`](https://github.com/FakeBuild/fake-bootstrap/tree/local_tool) branch of `fake-bootstrap` for ideas to bootstrap in your CI process.

To run fake use `dotnet fake --version`. To restore/download fake on another machine use `dotnet tool restore` after this command `dotnet fake` should work as expected.

* Install FAKE as a global `dotnet tool` (easiest, but needs [.NET Core SDK](https://dotnet.microsoft.com/download)):
* To install FAKE globally, run:
<pre><code class="lang-bash">
Expand Down Expand Up @@ -65,9 +79,9 @@ There are various ways to install FAKE 5:
<p>These scripts have no versioning story. You either need to take care of versions yourself (and lock them) or your builds might break on major releases.</p>
</div>

* Use it as a dotnet tool (legacy): Add `<DotNetCliToolReference Include="dotnet-fake" Version="5.*" />` to your dependencies and run `dotnet fake ...` instead of `fake ...`, see [this example](https://github.com/FakeBuild/fake-bootstrap/blob/master/dotnet-fake.csproj)
* (No longer recommended) Use it as a dotnet tool (legacy): Add `<DotNetCliToolReference Include="dotnet-fake" Version="5.*" />` to your dependencies and run `dotnet fake ...` instead of `fake ...`, see [this example](https://github.com/FakeBuild/fake-bootstrap/blob/master/dotnet-fake.csproj)

* Bootstrap via paket `clitool` (legacy), this is basically the same as `DotNetCliToolReference` but managed via paket. See the [`paket_clitool`](https://github.com/FakeBuild/fake-bootstrap/tree/paket_clitool) branch of `fake-bootstrap` in particular the [build.proj](https://github.com/FakeBuild/fake-bootstrap/blob/paket_clitool/build.proj) file.
* (No longer recommended) Bootstrap via paket `clitool` (legacy), this is basically the same as `DotNetCliToolReference` but managed via paket. See the [`paket_clitool`](https://github.com/FakeBuild/fake-bootstrap/tree/paket_clitool) branch of `fake-bootstrap` in particular the [build.proj](https://github.com/FakeBuild/fake-bootstrap/blob/paket_clitool/build.proj) file.

now you can use

Expand Down
Loading