A typical case: your team has agreed that repository classes must end
with Repository. So far this gets challenged in PR reviews.
With CodeCharter it is enforced by the build.
Create the rule set in the repo
In the repo root:
mkdir -p .codecharter/rules
All .ccr files go into this directory.
Write the rule
.codecharter/rules/repository-naming.ccr:
@name "Repository class must end in 'Repository'"
@severity error
@category "Naming"
@description "Implementations of the Repository pattern must have a 'Repository' suffix for discoverability"
@recommendation "Rename the class to end with 'Repository', e.g. 'UserData' -> 'UserRepository'"
from t in Types
where t.Kind == "Class"
where t.Namespace.StartsWith("Acme.Infrastructure.Repositories")
where !t.IsAbstract
where !t.Name.EndsWith("Repository")
select t
Anatomy:
@nameis the human-readable title shown in tooling.@severityisinfo,warn, orerror.@categorygroups the rule in the output.@descriptionexplains what is being checked.@recommendationsays how to fix it.- Body: a LINQ query against the schema. Here we look for classes in the repository namespace that are not abstract and whose name does not end with "Repository".
Try it locally
codecharter analyze .
If you have a class named UserData in the repository namespace,
it should now appear as an error.
What else you can express
The DSL is a subset of LINQ. You can access all type, method, property, field, event, namespace, and assembly properties. Examples:
# Find methods without CancellationToken
from m in Methods
where m.IsAsync
where !m.Parameters.Any(p => p.TypeShortName == "CancellationToken")
where m.AccessModifier == "Public"
select m
# Layer violation: Domain references Web
from t in Types
where t.Namespace.StartsWith("Acme.Domain")
where t.UsedTypes.Any(u => u.Namespace.StartsWith("Acme.Web"))
select t
# Classes with too many methods
from t in Types
where t.Kind == "Class"
where t.NumberOfMethods > 25
select t
Schema overview and further details under Syntax reference.
Best practices for custom rules
- One
.ccrper rule. This makes versioning and searching easier. - Descriptive file names. They appear in build logs.
- Honest
@recommendation. If the recommendation is unhelpful, developers will disable the rule rather than fix the code. - Start small. A rule that produces 50 findings cannot be rolled out.
Downgrade it to
warnor write it more specifically.
More under Best practices.