Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .diary/docs-refresh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## Rolling state
- Goal: Refresh README structure and CI/build package guidance for RazorStyle.
- Current plan: Complete README refresh and broaden repo CI detection.
- Open questions/risks: Badge rendering depends on shields.io and NuGet package metadata availability.
- Next actions: Review final README in rendered Markdown if desired.
- Key paths: README.md, Directory.Build.props

## Session log
### 2026-05-02 03:22 +01:00 (feature/docs-refresh)
- Refresh README [docs] (impact: low)
- Why: User requested badges, contents, clearer package guidance, build integration before CLI, and richer rule descriptions.
- Change: Rewrote README structure with NuGet version/download badges, contents, package choice guidance, build integration, CLI usage, and rule descriptions. (files: README.md | cmds: `git diff --check`)
- Notes: No production or test code changed.
### 2026-05-02 03:32 +01:00 (feature/docs-refresh)
- Broaden CI detection [build] (impact: low)
- Why: Azure DevOps should set CI mode through `TF_BUILD`, with reasonable support for other common CI hosts.
- Change: `ContinuousIntegrationBuild` now auto-enables for GitHub Actions, Azure DevOps, generic `CI=true`, TeamCity, and Jenkins unless explicitly set; README documents the behaviour. (files: Directory.Build.props, README.md | cmds: `dotnet msbuild ... -getProperty:ContinuousIntegrationBuild`, `dotnet build PinguApps.RazorStyle.slnx --no-restore`, `git diff --check`)
### 2026-05-02 11:09 +01:00 (feature/docs-refresh)
- Reformat badges [docs] (impact: low)
- Why: User requested README badges grouped by package type with version/download rows.
- Change: Replaced inline badges under the README title with a Markdown table headed `CLI Tool` and `Build Package`. (files: README.md | cmds: `git diff --check -- README.md`)
10 changes: 9 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
<RepositoryType>git</RepositoryType>
<Configurations>Debug;Release</Configurations>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild>
<ContinuousIntegrationBuild Condition="
'$(ContinuousIntegrationBuild)' == ''
and (
'$(GITHUB_ACTIONS)' == 'true'
or '$(TF_BUILD)' == 'true'
or '$(CI)' == 'true'
or '$(TEAMCITY_VERSION)' != ''
or '$(JENKINS_URL)' != ''
)">true</ContinuousIntegrationBuild>
<Authors>PinguApps</Authors>
<Company>PinguApps</Company>
<Copyright>Copyright (c) PinguApps</Copyright>
Expand Down
141 changes: 86 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,87 @@
# RazorStyle

RazorStyle is an opinionated Razor style linter and enforcer for Blazor `.razor` files. It exists to make Razor markup consistent across a solution, either by checking files in CI or fixing files during local builds.
| | CLI Tool | Build Package |
| --- | --- | --- |
| Version | [![PinguApps.RazorStyle.Cli version](https://img.shields.io/nuget/v/PinguApps.RazorStyle.Cli?style=for-the-badge&label=PinguApps.RazorStyle.Cli)](https://www.nuget.org/packages/PinguApps.RazorStyle.Cli/) | [![PinguApps.RazorStyle version](https://img.shields.io/nuget/v/PinguApps.RazorStyle?style=for-the-badge&label=PinguApps.RazorStyle)](https://www.nuget.org/packages/PinguApps.RazorStyle/) |
| Downloads | [![PinguApps.RazorStyle.Cli downloads](https://img.shields.io/nuget/dt/PinguApps.RazorStyle.Cli?style=for-the-badge&label=CLI%20downloads)](https://www.nuget.org/packages/PinguApps.RazorStyle.Cli/) | [![PinguApps.RazorStyle downloads](https://img.shields.io/nuget/dt/PinguApps.RazorStyle?style=for-the-badge&label=build%20package%20downloads)](https://www.nuget.org/packages/PinguApps.RazorStyle/) |

It is distributed as two packages:
RazorStyle is an opinionated formatter and linter for Blazor `.razor` files. It exists to make component markup predictable across a codebase by enforcing a small set of layout and attribute-ordering rules that are easy to check in CI and easy to fix locally. The style is deliberately prescriptive: it favours consistency, readable diffs, and low-friction code review over preserving every author's preferred Razor layout.

- `PinguApps.RazorStyle.Cli`: a .NET tool named `razorstyle`.
- `PinguApps.RazorStyle`: an MSBuild integration package that runs RazorStyle during builds.
## Contents

- [Packages](#packages)
- [Build Integration](#build-integration)
- [CLI Usage](#cli-usage)
- [Rules](#rules)
- [RS0001 Attribute Wrapping](#rs0001-attribute-wrapping)
- [RS0002 Child Content Lines](#rs0002-child-content-lines)
- [RS0003 Attribute Order](#rs0003-attribute-order)

## Packages

RazorStyle is distributed in two forms:

- [`PinguApps.RazorStyle`](https://www.nuget.org/packages/PinguApps.RazorStyle/) is the NuGet build integration package. Use this when you want RazorStyle to run automatically as part of project builds. It is the best fit for shared enforcement because every developer and CI agent gets the same behaviour through `PackageReference`. By default, local builds fix files and CI builds check files when `ContinuousIntegrationBuild=true`. You can control whether it runs, whether it checks or fixes, and which rules are disabled through MSBuild properties.
- [`PinguApps.RazorStyle.Cli`](https://www.nuget.org/packages/PinguApps.RazorStyle.Cli/) is a .NET tool named `razorstyle`. Use this when you want an explicit command for local formatting, repository-wide checks, scripts, or CI jobs that should not depend on MSBuild. It is useful for one-off cleanup, pre-commit workflows, and direct control over the target path and disabled rules.

## Build Integration

Install the build package into a project that contains `.razor` files:

```powershell
dotnet add package PinguApps.RazorStyle
```

By default:

- local builds run `fix`
- CI builds run `check` when `ContinuousIntegrationBuild=true`
- `bin` and `obj` folders are excluded
- projects without `.razor` files are skipped

Override behaviour with MSBuild properties:

```xml
<PropertyGroup>
<RazorStyleEnabled>true</RazorStyleEnabled>
<RazorStyleCommand>check</RazorStyleCommand>
<DisableRS0001>false</DisableRS0001>
<DisableRS0002>false</DisableRS0002>
<DisableRS0003>false</DisableRS0003>
</PropertyGroup>
```

Use the build package when the formatting rule should be part of the project contract. It keeps enforcement close to the project, works naturally in CI, and avoids relying on each developer remembering to run a separate tool command.

This repository sets `ContinuousIntegrationBuild=true` automatically when it detects GitHub Actions, Azure DevOps, a generic `CI=true` environment, TeamCity, or Jenkins. If your own consuming project does not already do that, add the same property in your build or CI configuration so the build package switches from `fix` to `check` during CI.

## CLI Usage

Install the tool:

```powershell
dotnet tool install --global PinguApps.RazorStyle.Cli
```

Check files:

```powershell
razorstyle check .\src
```

Fix files:

```powershell
razorstyle fix .\src
```

Disable specific rules for a run:

```powershell
razorstyle check .\src --disable RS0001 --disable RS0003
```

Use the CLI when you want direct control over when RazorStyle runs. It is a good fit for local cleanup, manual checks before opening a PR, custom CI steps, and scripts that should target a particular folder.

## Rules

Expand All @@ -15,6 +91,8 @@ It is distributed as two packages:

### RS0001 Attribute Wrapping

`RS0001` keeps multi-attribute start tags readable by putting each additional attribute on its own aligned line. Tags with no attributes, or with a single attribute, stay inline so simple markup remains compact.

Before:

```razor
Expand All @@ -38,6 +116,8 @@ Single-attribute and attribute-free tags remain inline:

### RS0002 Child Content Lines

`RS0002` separates child content from the opening and closing tags. This makes inline element bodies easier to scan, gives nested markup room to breathe, and avoids small edits turning into noisy one-line diffs.

Before:

```razor
Expand All @@ -61,6 +141,8 @@ Self-closing tags are already valid:

### RS0003 Attribute Order

`RS0003` applies a stable attribute order so the important identity, styling, binding, event, content, accessibility, and fallback attributes appear in a predictable place. In broad terms, unique identity-style attributes such as `@key`, `@ref`, `name`, and `id` come first, followed by `class` and `style`, binding and value-related attributes, event callbacks, common HTML/component attributes, templated or child-content attributes, general attributes, `aria-*`, `data-*`, splatted `@attributes`, and boolean or conditional attributes near the end.

Before:

```razor
Expand All @@ -76,54 +158,3 @@ After:
data-track="save"
disabled />
```

## CLI Usage

Install the tool:

```powershell
dotnet tool install --global PinguApps.RazorStyle.Cli
```

Check files:

```powershell
razorstyle check .\src
```

Fix files:

```powershell
razorstyle fix .\src
```

## Build Integration

Install the build package into a project that contains `.razor` files:

```powershell
dotnet add package PinguApps.RazorStyle
```

By default:

- local builds run `fix`
- CI builds run `check` when `ContinuousIntegrationBuild=true`

Override behavior with MSBuild properties:

```xml
<PropertyGroup>
<RazorStyleEnabled>true</RazorStyleEnabled>
<RazorStyleCommand>check</RazorStyleCommand>
<DisableRS0001>false</DisableRS0001>
<DisableRS0002>false</DisableRS0002>
<DisableRS0003>false</DisableRS0003>
</PropertyGroup>
```

The CLI also supports per-rule disables:

```powershell
razorstyle check .\src --disable RS0001 --disable RS0003
```
Loading