blob: 986fd199502ac384691a036558e738e3c600b382 [file]
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://pinterest.github.io/ktlint/dev-snapshot/api/custom-rule-set/">
<link rel="prev" href="../custom-integration/">
<link rel="next" href="../custom-reporter/">
<link rel="icon" href="../../assets/images/favicon.ico">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<title>Custom rule set - Ktlint</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="pink" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#ktlint-ruleset-template" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
<aside class="md-banner md-banner--warning">
<div class="md-banner__inner md-grid md-typeset">
You're viewing the SNAPSHOT version of the documentation. Be sure to use the
<a href="../../../dev-snapshot/install/snapshot-build">
<strong>SNAPSHOT version of ktlint</strong>
</a>
, or go to the latest
<a href="../../..">
<strong>RELEASE version of the documentation</strong>
</a>
</div>
<script>var el=document.querySelector("[data-md-component=outdated]"),base=new URL("../.."),outdated=__md_get("__outdated",sessionStorage,base);!0===outdated&&el&&(el.hidden=!1)</script>
</aside>
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Ktlint" class="md-header__button md-logo" aria-label="Ktlint" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Ktlint
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Custom rule set
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="pink" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="pink" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/pinterest/ktlint" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2"/></svg>
</div>
<div class="md-source__repository">
pinterest/ktlint
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../install/setup/" class="md-tabs__link">
Installation
</a>
</li>
<li class="md-tabs__item">
<a href="../../rules/code-styles/" class="md-tabs__link">
Rules
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../overview/" class="md-tabs__link">
API
</a>
</li>
<li class="md-tabs__item">
<a href="../../faq/" class="md-tabs__link">
FAQ
</a>
</li>
<li class="md-tabs__item">
<a href="../../contributing/overview/" class="md-tabs__link">
Contributing
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Ktlint" class="md-nav__button md-logo" aria-label="Ktlint" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
Ktlint
</label>
<div class="md-nav__source">
<a href="https://github.com/pinterest/ktlint" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2"/></svg>
</div>
<div class="md-source__repository">
pinterest/ktlint
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_1" >
<label class="md-nav__link" for="__nav_1" id="__nav_1_label" tabindex="0">
<span class="md-ellipsis">
Home
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_1">
<span class="md-nav__icon md-icon"></span>
Home
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../quick-start/" class="md-nav__link">
<span class="md-ellipsis">
Quick start
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Installation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Installation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../install/setup/" class="md-nav__link">
<span class="md-ellipsis">
Recommended setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../install/cli/" class="md-nav__link">
<span class="md-ellipsis">
Command line
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../install/integrations/" class="md-nav__link">
<span class="md-ellipsis">
Integrations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../install/snapshot-build/" class="md-nav__link">
<span class="md-ellipsis">
Snapshot build
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Rules
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Rules
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../rules/code-styles/" class="md-nav__link">
<span class="md-ellipsis">
Code styles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../rules/standard/" class="md-nav__link">
<span class="md-ellipsis">
Standard rules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../rules/experimental/" class="md-nav__link">
<span class="md-ellipsis">
Experimental rules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../rules/dependencies/" class="md-nav__link">
<span class="md-ellipsis">
Dependencies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../rules/configuration-ktlint/" class="md-nav__link">
<span class="md-ellipsis">
KtLint configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../rules/configuration-intellij-idea/" class="md-nav__link">
<span class="md-ellipsis">
IntelliJ IDEA configuration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="">
<span class="md-ellipsis">
API
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
API
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../overview/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../custom-integration/" class="md-nav__link">
<span class="md-ellipsis">
Custom integration
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Custom rule set
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Custom rule set
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#ktlint-ruleset-template" class="md-nav__link">
<span class="md-ellipsis">
ktlint-ruleset-template
</span>
</a>
<nav class="md-nav" aria-label="ktlint-ruleset-template">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#gradle-build" class="md-nav__link">
<span class="md-ellipsis">
Gradle build
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rule" class="md-nav__link">
<span class="md-ellipsis">
Rule
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rule-set-provider" class="md-nav__link">
<span class="md-ellipsis">
Rule Set Provider
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#building-the-project" class="md-nav__link">
<span class="md-ellipsis">
Building the project
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#running-ktlint-cli-with-the-custom-ruleset" class="md-nav__link">
<span class="md-ellipsis">
Running Ktlint CLI with the custom ruleset
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../custom-reporter/" class="md-nav__link">
<span class="md-ellipsis">
Custom reporter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../badge/" class="md-nav__link">
<span class="md-ellipsis">
Badge
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Contributing
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Contributing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../contributing/overview/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../contributing/guidelines/" class="md-nav__link">
<span class="md-ellipsis">
Guidelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../contributing/code-of-conduct/" class="md-nav__link">
<span class="md-ellipsis">
Code of conduct
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#ktlint-ruleset-template" class="md-nav__link">
<span class="md-ellipsis">
ktlint-ruleset-template
</span>
</a>
<nav class="md-nav" aria-label="ktlint-ruleset-template">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#gradle-build" class="md-nav__link">
<span class="md-ellipsis">
Gradle build
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rule" class="md-nav__link">
<span class="md-ellipsis">
Rule
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rule-set-provider" class="md-nav__link">
<span class="md-ellipsis">
Rule Set Provider
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#building-the-project" class="md-nav__link">
<span class="md-ellipsis">
Building the project
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#running-ktlint-cli-with-the-custom-ruleset" class="md-nav__link">
<span class="md-ellipsis">
Running Ktlint CLI with the custom ruleset
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1>Custom rule set</h1>
<p>You can provide custom rules via a separate ruleset to Ktlint. A ruleset is a JAR containing one or more <a href="https://github.com/pinterest/ktlint/blob/master/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/Rule.kt">Rule</a>s. </p>
<p>See presentation <a href="../../assets/Ktlint%20-%20building%20a%20custom%20ruleset%20.pdf">How to build a custom ruleset</a> as starting point to build your custom ruleset. Or, directly clone the sample project is included in this repo under the <a href="https://github.com/pinterest/ktlint/tree/master/ktlint-ruleset-template">ktlint-ruleset-template</a> directory.</p>
<h2 id="ktlint-ruleset-template">ktlint-ruleset-template<a class="headerlink" href="#ktlint-ruleset-template" title="Permanent link">&para;</a></h2>
<h3 id="gradle-build">Gradle build<a class="headerlink" href="#gradle-build" title="Permanent link">&para;</a></h3>
<p>The <a href="https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-template/build.gradle.kts">Gradle build file</a> of the sample project includes the setup for:</p>
<ul>
<li>publishing the custom ruleset artifact to Maven</li>
<li>the custom Gradle task 'ktlintCheck' that is using the Ktlint CLI to run the rules provided by the ktlint project, as well as the custom rule(s) from this project on the project itself (<a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfood principle</a>).</li>
</ul>
<h3 id="rule">Rule<a class="headerlink" href="#rule" title="Permanent link">&para;</a></h3>
<p>The Rule contains the logic for linting and formatting the code. For example, see <a href="https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-template/src/main/kotlin/yourpkgname/NoVarRule.kt">NoVarRuleTest</a>. </p>
<p>A rule has to implement one or more of hooks below:</p>
<ul>
<li><code>Rule.beforeFirstNode</code></li>
<li><code>RuleAutocorrectApproveHandler.beforeVisitChildNodes</code></li>
<li><code>RuleAutocorrectApproveHandler.afterVisitChildNodes</code></li>
<li><code>Rule.afterLastNode</code></li>
</ul>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>See <code>ktlint-ruleset-standard</code> for examples of rules that implement the hooks above.</p>
</div>
<p>Upon traversal of the Abstract Syntax Tree (AST), the hooks of the Rule are visited as indicated by their names. The <a href="https://plugins.jetbrains.com/plugin/227-psiviewer">Jetbrains PsiViewer plugin for IntelliJ IDEA</a> is a convenient tool to inspect the AST for any piece of code.</p>
<p><img alt="Image" src="../../assets/images/psi-viewer.png" /></p>
<h3 id="rule-set-provider">Rule Set Provider<a class="headerlink" href="#rule-set-provider" title="Permanent link">&para;</a></h3>
<p>The RuleSetProvider provides new instances of the rule, see <a href="https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-template/src/main/kotlin/yourpkgname/CustomRuleSetProvider.kt">CustomRuleSetProvider</a> for an example.</p>
<p><code>ktlint</code> is relying on the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html">ServiceLoader</a> to discover all available "RuleSet"s on the classpath. For this, the RuleSetProvider needs to be registered in file <code>resources/META-INF/services/com.pinterest.ktlint.cli.ruleset.core.api.RuleSetV2Provider</code>, see <a href="https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-template/src/main/resources/META-INF/services/com.pinterest.ktlint.cli.ruleset.core.api.RuleSetV2Provider">Registration for Java ServiceLoader</a>.</p>
<h3 id="building-the-project">Building the project<a class="headerlink" href="#building-the-project" title="Permanent link">&para;</a></h3>
<div class="highlight"><span class="filename">Building the ktlint-ruleset-template</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>ktlint-ruleset-template/
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>$<span class="w"> </span>../gradlew<span class="w"> </span>build
</code></pre></div>
<h3 id="running-ktlint-cli-with-the-custom-ruleset">Running Ktlint CLI with the custom ruleset<a class="headerlink" href="#running-ktlint-cli-with-the-custom-ruleset" title="Permanent link">&para;</a></h3>
<div class="highlight"><span class="filename">Provide code sample that violates rule `custom:no-var</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>$<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s1">&#39;var v = 0&#39;</span><span class="w"> </span>&gt;<span class="w"> </span>test.kt
</code></pre></div>
<div class="highlight"><span class="filename">Running the ktlint-ruleset-template</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="hll">$<span class="w"> </span>ktlint<span class="w"> </span>-R<span class="w"> </span>build/libs/ktlint-ruleset-template.jar<span class="w"> </span>--log-level<span class="o">=</span>debug<span class="w"> </span>--relative<span class="w"> </span>test.kt
</span><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="m">18</span>:13:21.026<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.internal.RuleSetsLoader<span class="w"> </span>-<span class="w"> </span>JAR<span class="w"> </span>ruleset<span class="w"> </span>provided<span class="w"> </span>with<span class="w"> </span>path<span class="w"> </span><span class="s2">&quot;/../ktlint/ktlint-ruleset-template/build/libs/ktlint-ruleset-template.jar&quot;</span>
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="m">18</span>:13:21.241<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Discovered<span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="s2">&quot;baseline&quot;</span><span class="w"> </span>id.
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="m">18</span>:13:21.241<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Discovered<span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="s2">&quot;checkstyle&quot;</span><span class="w"> </span>id.
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="m">18</span>:13:21.241<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Discovered<span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="s2">&quot;json&quot;</span><span class="w"> </span>id.
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a><span class="m">18</span>:13:21.242<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Discovered<span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="s2">&quot;html&quot;</span><span class="w"> </span>id.
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a><span class="m">18</span>:13:21.242<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Discovered<span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="s2">&quot;plain&quot;</span><span class="w"> </span>id.
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a><span class="m">18</span>:13:21.242<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Discovered<span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="s2">&quot;sarif&quot;</span><span class="w"> </span>id.
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a><span class="m">18</span>:13:21.242<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>Initializing<span class="w"> </span><span class="s2">&quot;plain&quot;</span><span class="w"> </span>reporter<span class="w"> </span>with<span class="w"> </span><span class="o">{</span><span class="nv">verbose</span><span class="o">=</span>false,<span class="w"> </span><span class="nv">color</span><span class="o">=</span>false,<span class="w"> </span><span class="nv">color_name</span><span class="o">=</span>DARK_GRAY<span class="o">}</span>
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a><span class="o">[</span>DEBUG<span class="o">]</span><span class="w"> </span>Rule<span class="w"> </span>with<span class="w"> </span>id<span class="w"> </span><span class="s1">&#39;standard:max-line-length&#39;</span><span class="w"> </span>should<span class="w"> </span>run<span class="w"> </span>after<span class="w"> </span>the<span class="w"> </span>rule<span class="w"> </span>with<span class="w"> </span>id<span class="w"> </span><span class="s1">&#39;trailing-comma&#39;</span>.<span class="w"> </span>However,<span class="w"> </span>the<span class="w"> </span>latter<span class="w"> </span>rule<span class="w"> </span>is<span class="w"> </span>not<span class="w"> </span>loaded<span class="w"> </span>and<span class="w"> </span>is<span class="w"> </span>allowed<span class="w"> </span>to<span class="w"> </span>be<span class="w"> </span>ignored.<span class="w"> </span>For<span class="w"> </span>best<span class="w"> </span>results,<span class="w"> </span>it<span class="w"> </span>is<span class="w"> </span>advised<span class="w"> </span>load<span class="w"> </span>the<span class="w"> </span>rule.
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a><span class="o">[</span>DEBUG<span class="o">]</span><span class="w"> </span>Rules<span class="w"> </span>will<span class="w"> </span>be<span class="w"> </span>executed<span class="w"> </span><span class="k">in</span><span class="w"> </span>order<span class="w"> </span>below<span class="w"> </span><span class="o">(</span>unless<span class="w"> </span>disabled<span class="o">)</span>:
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a><span class="w"> </span>-<span class="w"> </span>standard:filename,<span class="w"> </span>
<a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a><span class="w"> </span>-<span class="w"> </span>standard:final-newline,<span class="w"> </span>
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a><span class="w"> </span>-<span class="w"> </span>standard:chain-wrapping,<span class="w"> </span>
<a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a><span class="w"> </span>-<span class="w"> </span>standard:colon-spacing,<span class="w"> </span>
<a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a><span class="w"> </span>-<span class="w"> </span>standard:comma-spacing,<span class="w"> </span>
<a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a><span class="w"> </span>-<span class="w"> </span>standard:comment-spacing,<span class="w"> </span>
<a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a><span class="w"> </span>-<span class="w"> </span>standard:curly-spacing,<span class="w"> </span>
<a id="__codelineno-2-20" name="__codelineno-2-20" href="#__codelineno-2-20"></a><span class="w"> </span>-<span class="w"> </span>standard:dot-spacing,<span class="w"> </span>
<a id="__codelineno-2-21" name="__codelineno-2-21" href="#__codelineno-2-21"></a><span class="w"> </span>-<span class="w"> </span>standard:import-ordering,<span class="w"> </span>
<a id="__codelineno-2-22" name="__codelineno-2-22" href="#__codelineno-2-22"></a><span class="w"> </span>-<span class="w"> </span>standard:keyword-spacing,<span class="w"> </span>
<a id="__codelineno-2-23" name="__codelineno-2-23" href="#__codelineno-2-23"></a><span class="w"> </span>-<span class="w"> </span>standard:modifier-order,<span class="w"> </span>
<a id="__codelineno-2-24" name="__codelineno-2-24" href="#__codelineno-2-24"></a><span class="w"> </span>-<span class="w"> </span>standard:no-blank-line-before-rbrace,<span class="w"> </span>
<a id="__codelineno-2-25" name="__codelineno-2-25" href="#__codelineno-2-25"></a><span class="w"> </span>-<span class="w"> </span>standard:no-consecutive-blank-lines,<span class="w"> </span>
<a id="__codelineno-2-26" name="__codelineno-2-26" href="#__codelineno-2-26"></a><span class="w"> </span>-<span class="w"> </span>standard:no-empty-class-body,<span class="w"> </span>
<a id="__codelineno-2-27" name="__codelineno-2-27" href="#__codelineno-2-27"></a><span class="w"> </span>-<span class="w"> </span>standard:no-line-break-after-else,<span class="w"> </span>
<a id="__codelineno-2-28" name="__codelineno-2-28" href="#__codelineno-2-28"></a><span class="w"> </span>-<span class="w"> </span>standard:no-line-break-before-assignment,<span class="w"> </span>
<a id="__codelineno-2-29" name="__codelineno-2-29" href="#__codelineno-2-29"></a><span class="w"> </span>-<span class="w"> </span>standard:no-multi-spaces,<span class="w"> </span>
<a id="__codelineno-2-30" name="__codelineno-2-30" href="#__codelineno-2-30"></a><span class="w"> </span>-<span class="w"> </span>standard:no-semi,<span class="w"> </span>
<a id="__codelineno-2-31" name="__codelineno-2-31" href="#__codelineno-2-31"></a><span class="w"> </span>-<span class="w"> </span>standard:no-trailing-spaces,<span class="w"> </span>
<a id="__codelineno-2-32" name="__codelineno-2-32" href="#__codelineno-2-32"></a><span class="w"> </span>-<span class="w"> </span>standard:no-unit-return,<span class="w"> </span>
<a id="__codelineno-2-33" name="__codelineno-2-33" href="#__codelineno-2-33"></a><span class="w"> </span>-<span class="w"> </span>standard:no-unused-imports,<span class="w"> </span>
<a id="__codelineno-2-34" name="__codelineno-2-34" href="#__codelineno-2-34"></a><span class="w"> </span>-<span class="w"> </span>standard:no-wildcard-imports,<span class="w"> </span>
<a id="__codelineno-2-35" name="__codelineno-2-35" href="#__codelineno-2-35"></a><span class="w"> </span>-<span class="w"> </span>standard:op-spacing,<span class="w"> </span>
<a id="__codelineno-2-36" name="__codelineno-2-36" href="#__codelineno-2-36"></a><span class="w"> </span>-<span class="w"> </span>standard:parameter-list-wrapping,<span class="w"> </span>
<a id="__codelineno-2-37" name="__codelineno-2-37" href="#__codelineno-2-37"></a><span class="w"> </span>-<span class="w"> </span>standard:paren-spacing,<span class="w"> </span>
<a id="__codelineno-2-38" name="__codelineno-2-38" href="#__codelineno-2-38"></a><span class="w"> </span>-<span class="w"> </span>standard:range-spacing,<span class="w"> </span>
<a id="__codelineno-2-39" name="__codelineno-2-39" href="#__codelineno-2-39"></a><span class="w"> </span>-<span class="w"> </span>standard:string-template,<span class="w"> </span>
<a id="__codelineno-2-40" name="__codelineno-2-40" href="#__codelineno-2-40"></a><span class="hll"><span class="w"> </span>-<span class="w"> </span>custom:no-var,<span class="w"> </span>
</span><a id="__codelineno-2-41" name="__codelineno-2-41" href="#__codelineno-2-41"></a><span class="w"> </span>-<span class="w"> </span>standard:indent,<span class="w"> </span>
<a id="__codelineno-2-42" name="__codelineno-2-42" href="#__codelineno-2-42"></a><span class="w"> </span>-<span class="w"> </span>standard:max-line-length
<a id="__codelineno-2-43" name="__codelineno-2-43" href="#__codelineno-2-43"></a><span class="hll"><span class="sb">`</span>text<span class="w"> </span>test.kt:1:1:<span class="w"> </span>Unexpected<span class="w"> </span>var,<span class="w"> </span>use<span class="w"> </span>val<span class="w"> </span>instead<span class="w"> </span><span class="o">(</span>cannot<span class="w"> </span>be<span class="w"> </span>auto-corrected<span class="o">)</span><span class="sb">`</span>
</span><a id="__codelineno-2-44" name="__codelineno-2-44" href="#__codelineno-2-44"></a><span class="m">18</span>:13:21.893<span class="w"> </span><span class="o">[</span>main<span class="o">]</span><span class="w"> </span>DEBUG<span class="w"> </span>com.pinterest.ktlint.Main<span class="w"> </span>-<span class="w"> </span>872ms<span class="w"> </span>/<span class="w"> </span><span class="m">1</span><span class="w"> </span>file<span class="o">(</span>s<span class="o">)</span><span class="w"> </span>/<span class="w"> </span><span class="m">1</span><span class="w"> </span>error<span class="o">(</span>s<span class="o">)</span>
</code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>Multiple custom rule sets can be loaded at the same time.</p>
</div>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["navigation.tabs", "navigation.tabs.sticky", "navigation.sections", "navigation.expand", "search.suggest", "search.share", "content.code.copy"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
</body>
</html>