Skip to content

Commit

Permalink
Merge pull request #225 from 1eyewonder/using-fake-docs
Browse files Browse the repository at this point in the history
Update Getting Started Docs: Calling Analyzers w/ FAKE
  • Loading branch information
TheAngryByrd authored Jan 28, 2025
2 parents ac7d475 + 6798d4d commit 9a294eb
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 63 deletions.
4 changes: 2 additions & 2 deletions docs/content/Dual Analyzer.fsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(**
---
category: end-users
categoryindex: 1
index: 3
categoryindex: 2
index: 2
---
# Writing an analyzer for both console and editor
Expand Down
4 changes: 2 additions & 2 deletions docs/content/Getting Started Writing.fsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(**
---
category: end-users
categoryindex: 1
index: 2
categoryindex: 2
index: 1
---
# Getting started writing an analyzer
Expand Down
4 changes: 2 additions & 2 deletions docs/content/Programmatic access.fsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(**
---
category: end-users
categoryindex: 1
index: 4
categoryindex: 2
index: 3
---
# Programmatically running an analyzer
Expand Down
4 changes: 2 additions & 2 deletions docs/content/Running during CI.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
category: end-users
categoryindex: 1
index: 6
categoryindex: 2
index: 5
---

# Running analyzers during continuous integration
Expand Down
4 changes: 2 additions & 2 deletions docs/content/Unit Testing.fsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(**
---
category: end-users
categoryindex: 1
index: 5
categoryindex: 2
index: 4
---
# Unit testing an analyzer
Expand Down
27 changes: 27 additions & 0 deletions docs/content/getting-started/CLI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
category: getting-started
categoryindex: 1
index: 3
---

# Command Line Arguments

## Example Command

When running the CLI tool from the command line (and after installing analyzers), the minimum console arguments you need to provide is the path to the project file(s) you want to analyze.

```shell
dotnet fsharp-analyzers --project ./YourProject.fsproj --analyzers-path ./path/to/analyzers/directory
```

⚠️ If you don't provide the `--analyzers-path` argument, it will default to `packages/analyzers`. If you are using Paket with a group called `analyzers`, this default path should work for you.

## Viewing Additional Commands

You can view the full list of commands available by running:

```shell
dotnet fsharp-analyzers --help
```

[Next]({{fsdocs-next-page-link}})
26 changes: 26 additions & 0 deletions docs/content/getting-started/Configuring for IDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
category: getting-started
categoryindex: 1
index: 2
---

# Configuring for the IDE

## Visual Studio Code

In order to configure analyzers for VSCode, you will need to update your project's `.vscode/settings.json` file or your user settings. You should need the settings shown below.

```json
{
"FSharp.enableAnalyzers": true,
"FSharp.analyzersPath": ["path/to/analyzers/directory"]
}
```

📓 Note: Issue created [here](https://github.com/ionide/FsAutoComplete/issues/1350) regarding analyzers & SDK mismatches in the logs

After saving your new settings, make sure to restart VSCode. Once VSCode restarts, you should be able to test and see if the analyzers are working by opening a F# file in your workspace and entering the following code

![Analyzers Inline Warning](../../images/analyzers-inline-warning.png)

[Next]({{fsdocs-next-page-link}})
50 changes: 50 additions & 0 deletions docs/content/getting-started/Installing Analyzers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
category: getting-started
categoryindex: 1
index: 1
---
# Installation

## Installing the Tool

A dotnet CLI tool, called [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK/), is used to run analyzers outside the context of an IDE. Add it to your tool-manifest with:

```shell
dotnet tool install fsharp-analyzers --create-manifest-if-needed
```

## Installing Analyzers

### Suggested Packages

1. [Ionide Analyzers](https://github.com/ionide/FSharp.Analyzers.SDK/)
2. [G-Research Analyzers](https://github.com/G-Research/fsharp-analyzers/)

### Nuget

If you are using Nuget as your package manager, add the `PackageReference` pointing to your favorite analyzers to the `.fsproj` file of the project you want to analyze.

```xml
<PackageReference Include="G-Research.FSharp.Analyzers" Version="0.12.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Ionide.Analyzers" Version="0.28.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
```

### Paket

If you are using Paket as your package manager, add the package to your `paket.dependencies` file. The example below uses a paket group, but it is not required.

```paket
group analyzers
source https://api.nuget.org/v3/index.json
nuget Ionide.Analyzers
nuget G-Research.FSharp.Analyzers
```

[Next]({{fsdocs-next-page-link}})
Original file line number Diff line number Diff line change
@@ -1,57 +1,45 @@
---
category: end-users
category: getting-started
categoryindex: 1
index: 1
index: 4
---

# Getting started using analyzers
# MSBuild

## Premise
## Using Analyzer Build Target in a Project

We assume the analyzers you want to use are distributed as a nuget package.
The path to the analyzer DLL files could be tricky to get right across a wide range of setups. Luckily, we can use a MSBuild custom target to take care of the path construction. Add [FSharp.Analyzers.Build](https://www.nuget.org/packages/FSharp.Analyzers.Build) to your project. This imports a new target to your project file (`AnalyzeFSharpProject`) and will allow us to easily run the analyzers for our project.

## Using analyzers in a single project
### Installing Target via Nuget

### Raw command line

A dotnet CLI tool, called [fsharp-analyzers](https://www.nuget.org/packages/fsharp-analyzers), is used to run analyzers outside the context of an IDE.
Add it to your tool-manifest with:
```shell
dotnet tool install fsharp-analyzers
```

Next, add the `PackageReference` pointing to your favorite analyzers to the `.fsproj` file of the project you want to analyze:
If you are using Nuget, add it to your `.fsproj` file:

```xml
<PackageReference Include="G-Research.FSharp.Analyzers" Version="0.4.0">
<PackageReference Include="FSharp.Analyzers.Build" Version="0.2.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>analyzers</IncludeAssets>
<IncludeAssets>build</IncludeAssets>
</PackageReference>
```

At the time of writing, the [G-Research analyzers](https://github.com/g-research/fsharp-analyzers) [package](https://www.nuget.org/packages/G-Research.FSharp.Analyzers) contains the only analyzers compatible with the latest CLI tool.
With the package downloaded, we can run the CLI tool:
### Installing Target via Paket

```shell
dotnet fsharp-analyzers --project ./YourProject.fsproj --analyzers-path C:\Users\yourusername\.nuget\packages\g-research.fsharp.analyzers\0.4.0\analyzers\dotnet\fs\ --verbosity d
```
If you are using Paket, add it to your `paket.dependencies`

### Using an MSBuild target
```paket
group analyzers
source https://api.nuget.org/v3/index.json
As you can see, the path to the analyzer DLL files could be tricky to get right across a wide range of setups.
Luckily, we can use an MSBuild custom target to take care of the path construction.
nuget FSharp.Analyzers.Build
```

Add [FSharp.Analyzers.Build](https://www.nuget.org/packages/FSharp.Analyzers.Build) to your `fsproj`:
as well as the `paket.references` of your project:

```xml
<PackageReference Include="FSharp.Analyzers.Build" Version="0.2.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>build</IncludeAssets>
</PackageReference>
```paket
group analyzers
FSharp.Analyzers.Build
```

This imports a new target to your project file: `AnalyzeFSharpProject`.
And will allow us to easily run the analyzers for our project.
### Configuring the Build Target

Before we can run `dotnet msbuild /t:AnalyzeFSharpProject`, we need to specify our settings in a property called `FSharpAnalyzersOtherFlags`:

Expand All @@ -62,21 +50,25 @@ Before we can run `dotnet msbuild /t:AnalyzeFSharpProject`, we need to specify o
```

To locate the analyzer DLLs in the filesystem, we use the variable `$(PkgG-Research_FSharp_Analyzers)`. It's produced by NuGet and normalized to be usable by [MSBuild](https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#generatepathproperty).
In general, a `Pkg` prefix is added and dots in the package ID are replaced by underscores. But make sure to look at the [nuget.g.props](https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#restore-outputs) file in the `obj` folder for the exact string.
In general, a `Pkg` prefix is added and dots in the package ID are replaced by underscores. But make sure to look at the [nuget.g.props](https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#restore-outputs) file in the `obj` folder for the exact string.

The `/analyzers/dotnet/fs` subpath is a convention analyzer authors should follow when creating their packages.

### Running the Build Target

At last, you can run the analyzer from the project folder:

```shell
dotnet msbuild /t:AnalyzeFSharpProject
```

Note: if your project has multiple `TargetFrameworks` the tool will be invoked for each target framework.
📓 Note: If your project has multiple `TargetFrameworks` the tool will be invoked for each target framework.

## Using Analyzer Build Target in a Solution

## Using analyzers in a solution
Adding the custom target from above to all `.fsproj` files of a solution doesn't scale very well. We can use the MSBuild infrastructure to add the needed package reference and the MSBuild target to all projects in one go.

Adding the custom target from above to all `.fsproj` files of a solution doesn't scale very well.
So we use the MSBuild infrastructure to add the needed package reference and the MSBuild target to all projects in one go.
### Setting up Directory.Build.props

We start with adding the `PackageReference` pointing to your favorite analyzers to the [Directory.Build.props](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory?view=vs-2022) file.
This adds the package reference to all `.fsproj` files that are in a subfolder of the file location of `Directory.Build.props`:
Expand All @@ -94,8 +86,10 @@ This adds the package reference to all `.fsproj` files that are in a subfolder o
</ItemGroup>
```

Likewise we add the `FSharpAnalyzersOtherFlags` property to the [Directory.Build.targets](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory?view=vs-2022) file.
This is effectively the same as adding a property to each `*proj` file which exists in a subfolder.
### Setting up Directory.Build.targets

Likewise we add the `FSharpAnalyzersOtherFlags` property to the [Directory.Build.targets](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory?view=vs-2022) file. For first time MSBuild users, this is effectively the same as adding a property to each `*proj` file which exists in a subfolder.

```xml
<Project>
<PropertyGroup>
Expand All @@ -106,34 +100,49 @@ This is effectively the same as adding a property to each `*proj` file which exi
</Project>
```

⚠️ We are adding the `FSharpAnalyzersOtherFlags` property to our **Directory.Build.targets** and **not to** any **Directory.Build.props** file!
MSBuild will first evaluate `Directory.Build.props` which has no access to the generated nuget.g.props. `$(PkgG-Research_FSharp_Analyzers)` won't be known at this point. `Directory.Build.targets` is evaluated after the project file and has access to `Pkg` generated properties.
⚠️ We are adding the `FSharpAnalyzersOtherFlags` property to our **Directory.Build.targets** and **not to** any **Directory.Build.props** file! MSBuild will first evaluate `Directory.Build.props` which has no access to the generated nuget.g.props. `$(PkgG-Research_FSharp_Analyzers)` won't be known at this point. `Directory.Build.targets` is evaluated after the project file and has access to `Pkg` generated properties.

### All projects in the solution
### Run Target for All Projects in the Solution

We can run the `AnalyzeFSharpProject` target against all projects in a solution

```shell
dotnet msbuild YourSolution.sln /t:AnalyzeFSharpProject
```

### Select specific projects
### Configuring Specific Projects to Run

As we don't want to target all projects in the solution, we create a second custom MSBuild target that calls the project-specific target for all relevant projects.
As we may not always want to target every project in a solution, we can create a second custom MSBuild target that calls the project-specific target for all relevant projects.
Add the following custom target to the [Directory.Solution.targets](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-solution-build?view=vs-2022) file to be able to invoke analysis from all selected projects in one simple command:

```xml
<Project>
<ItemGroup>
<ProjectsToAnalyze Include="src/**/*.fsproj" />
</ItemGroup>

<Target Name="AnalyzeSolution">
<MSBuild Projects="@(ProjectsToAnalyze)" Targets="AnalyzeFSharpProject" />
</Target>
</Project>
```

You can also exclude certain projects from the analysis if they fall within the same pattern

```xml
<Project>
<ItemGroup>
<ProjectsToAnalyze Include="src/**/*.fsproj" Exclude="src/**/Special.fsproj" />
</ItemGroup>

<Target Name="AnalyzeSolution">
<MSBuild Projects="@(ProjectsToAnalyze)" Targets="AnalyzeFSharpProject" />
</Target>
</Project>
```

### Running the Solution Target

At last, you can run the analyzer from the solution folder:

```shell
Expand All @@ -142,15 +151,15 @@ dotnet msbuild /t:AnalyzeSolution

Note: we passed the `--code-root` flag so that the `*.sarif` report files will report file paths relative to this root. This can be imported for certain editors to function properly.

## MSBuild tips and tricks
## MSBuild Tips and Tricks

MSBuild can be overwhelming for the uninitiated. Here are some tricks we've seen in the wild:

### Use well-known properties
### Use Well-Known Properties

Checkout the [MSBuild reserved and well-known properties](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties?view=vs-2022) to use existing variables like `$(MSBuildProjectFile)`.

### Wrap path arguments in quotes
### Wrap Path Arguments in Quotes

As MSBuild is all XML, you can use `&quot;` to wrap evaluated values in quotes:

Expand All @@ -160,7 +169,7 @@ As MSBuild is all XML, you can use `&quot;` to wrap evaluated values in quotes:
</PropertyGroup>
```

### Extend `<FSharpAnalyzersOtherFlags>` in multiple lines
### Extend `<FSharpAnalyzersOtherFlags>` in Multiple Lines

You can extend the value of `$(FSharpAnalyzersOtherFlags)` by setting it again in multiple lines:

Expand All @@ -173,7 +182,7 @@ You can extend the value of `$(FSharpAnalyzersOtherFlags)` by setting it again i
</PropertyGroup>
```

### Verify parameters are present
### Verify Parameters are Present

It can be a bit confusing to find out if a variable contains the value you think it does.
We often add a dummy target to a project to print out some values:
Expand All @@ -186,4 +195,4 @@ We often add a dummy target to a project to print out some values:

Run `dotnet msbuild YourProject.fsproj /t:Dump` and verify that `CodeRoot` has a value or not.

[Next]({{fsdocs-next-page-link}})
[Next]({{fsdocs-next-page-link}})
Binary file added docs/images/analyzers-inline-warning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You can also set up a run configuration of FSharp.Analyzers.Cli in your favorite

## Using Analyzers

Checkout our [Getting Started](https://ionide.io/FSharp.Analyzers.SDK/content/Getting%20Started%20Using.html) guide for analyzer users!
Checkout our [Getting Started](https://ionide.io/FSharp.Analyzers.SDK/content/getting-started/Installing%20Analyzers.html) guide for analyzer users!

## Writing Analyzers

Expand Down
Loading

0 comments on commit 9a294eb

Please sign in to comment.