Opinionated-csharp-todos inspects that your TODO comments follow a pattern.
It is quite messy to have a variety of TODO comment styles in your code:
-
New developers are confused as which style they should use.
For example, if you mix case, is it
// todo
or// Todo
or// TODO
?→ You want a uniform style throught your code base.
-
The set of the prefixes is not well-defined. Certain tools support by default only a limited set of prefixes.
For example, Microsoft Visual Studio supports by default
HACK
,TODO
,UNDONE
andUnresolvedMergeConflict
(see this page). On the other hand, JetBrains Rider supports by defaultTODO
andBUG
(see this page). Both tools support adding custom prefixes (a.k.a, tags or tokens).→ You want to have a separate IDE-independent tool which ensures that the established convention is followed in the code base. Best if done in continuous integration.
-
Bare TODOs can be daunting in larger code bases with multiple contributors. Single
// TODO
without further information such as the author and the date of the comment can be confusing or even overwhelming, especially to new developers.For example, if you have to work on a part of the code base with a highly relevant TODO, how are you supposed to contact the person who left it there to gain further insights and background knowledge?
While using
git blame
might a be a solution up to a certain degree, this does not work whenever the copy/pasted code includes the TODOs. This situation often happens in refactorings when the "refactorer" is not the author of the code.→ You want the information about the author and the time stamp included in the TODOs. This additional information should be structured in an uniform manner.
-
Structured information is necessary for further processing. Bare TODOs bar that possibility.
For example, imagine you would like to create an additional tool to analyze the TODOs and create Github issues automatically. You might want to include the information such as timestamp, due date, author and issue tag in the TODO.
→ Though complex examination of the comment structure is out-of-scope for Opinionated-csharp-todos, it is a good idea to check that the TODO comments at least match the expected patterns and inform the developer as soon as possible if some of the comments do not match.
IDEs and extensions. While popular IDEs support the TODO comments themselves (e.g., Task lists in Visual Studio) and also provide ground for many extensions (e.g., this extension and that extension), these tools are difficult or impossible to put into the continuous integration since they lack a command-line interface.
At best, you could use them to re-format and inspect the TODOs manually.
TODOs-as-a-service. There is a service, Tickgit, that you connect with the repository to inspect
your TODOs and extract the extra information such as the author and
the time stamp using git blame
. Unfortunately, this typically breaks even in
smaller teams whenever the person refactoring is not the author of
the original code.
Command-line tools. We searched nuget.org when we started developing the tool (July 2020). There were only a few related tools, none of which could enforce arbitrary patterns:
-
DatedTodo inspects the TODOs, parses the due date and raises an alarm if some of the TODOs are due.
-
TodoCommentReporter is a Roslyn diagnostic analyzer that reports the TODOs in your code base.
-
FixMe emits the TODO comments during the build.
Opinionated-csharp-todos is available as a dotnet tool.
Either install it globally:
dotnet tool install -g OpinionatedCsharpTodos
or locally (if you use tool manifest, see this Microsoft tutorial):
dotnet tool install OpinionatedCsharpTodos
To obtain an overview of the command-line arguments, use --help
:
dotnet doctest-csharp --help
OpinionatedCsharpTodos:
Examines and collects the TODOs from your C# code.
Usage:
OpinionatedCsharpTodos [options]
Options:
-i, --inputs <inputs> (REQUIRED) Glob patterns of the files to be inspected
-e, --excludes <excludes> Glob patterns of the files to be excluded from inspection
--prefixes <prefixes> Prefix regular expressions marking the TODOs. [Default: ^TODO ^BUG ^HACK]
--disallowed-prefixes <disallowed-prefixes> Prefix regular expressions which should not occur. [Default: ^DONT-CHECK-IN ^Todo ^todo ^ToDo ^Bug ^bug ^Hack ^hack]
--suffixes <suffixes> Suffix regular expressions that TODOs must conform to. [Default: ^ \([^)]+, [0-9]{4}-[0-9]{2}-[0-9]{2}\): .]
--case-insensitive If set, the regular expressions are applied as case-insensitive
--report-path <report-path> If set, outputs the TODOs as a JSON (the path '-' denotes STDOUT).
--verbose If set, makes the console output more verbose
--version Show version information
-?, -h, --help Show help and usage information
You run opinionated-csharp-todos through dotnet
.
To obtain help:
dotnet opinionated-csharp-todos --help
You specify the files containing TODOs using glob patterns:
dotnet opinionated-csharp-todos --inputs "SomeProject/**/*.cs"
Multiple patterns are also possible (we use '\' for line continuation here):
dotnet opinionated-csharp-todos \
--inputs "SomeProject/**/*.cs" \
"AnotherProject/**/*.cs"
Sometimes you need to exclude files, e.g., when your solution contains third-party code which you do not want to scan.
You can provide the glob pattern for the files to be excluded with --excludes
:
dotnet opinionated-csharp-todos \
--inputs "**/*.cs" \
--excludes "**/obj/**"
The comments are inspected based on their prefix and their suffix. Namely, opnionated-csharp-todos considers only comments which match a certain set of prefix patterns.
If the comment matches one of the special prefixes (given in --prefixes
,
see below), the remainder of the comment (the suffix) needs to match one of
the suffix patterns (given in --suffixes
, see below). Otherwise, the comment
is reported as invalid.
Additionally, you can specify a list of disallowed prefixes (given in
--disallowed-prefixes
, see below), so that all
comments matching those are also reported as invalid. The disallowed prefixes
are particularly useful if you want to mark parts of the code which should not
be checked in into the version control (e.g, // DONT-CHECK-IN
) or if you
want to enforce consistency in prefixes (e.g., disallow // todo
).
Prefixes are specified as regular expressions using --prefixes
.
For example, if you only want to scan for // TODO
and // BUG
:
dotnet opinionated-csharp-todos \
--inputs "**/*.cs" \
--prefixes "^TODO" "^BUG"
Disallowed prefixes. You can make opinionated-csharp-comments fail whenever
one of the disallowed prefixes is encountered specified as regular expressions
using --disallowed-prefixes
.
This is particularly handy if you want to include the tool in your pre-commit checks to make sure you do not check in, say, unfinished work.
For example, if you want the tool to fail on // DONT-CHECK-IN
and // DEBUG
:
dotnet opinionated-csharp-todos \
--inputs "**/*.cs" \
--disallowed-prefixes "^DONT-CHECK-IN" "^DEBUG"
Suffixes are usually also required to follow the convention(s). You can
specify the patterns as regular expressions using --suffix
.
For example, to enforce suffix to match // TODO (mristin, 2020-07-20): ...
:
dotnet opinionated-csharp-todos \
--inputs "**/*.cs" \
--suffixes '^ \([^)]+, [0-9]{4}-[0-9]{2}-[0-9]{2}\): '
We provide the defaults for --prefixes
, --disallowed-prefixes
and
--suffixes
which probably work in most of the cases:
--prefixes
:^TODO
,^BUG
,^HACK
--disallowed-prefixes
:^DONT-CHECK-IN
,^Todo
,^todo
,^ToDo
,^Bug
,^bug
,^Hack
,^hack
--suffixes
:^ \([^)]+, [0-9]{4}-[0-9]{2}-[0-9]{2}\): .
Opinionated-csharp-todos scans the files and reports the collected TODOs to the
standard output as text.
In cases where you would like to post-process the results, you can
save the report as a JSON file using --report-path
.
For example:
dotnet opinionated-csharp-todos \
--inputs "**/*.cs" \
--report-path /tmp/some-report.json
If you provide -
, the JSON report is written to the standard output:
dotnet opinionated-csharp-todos \
--inputs "**/*.cs" \
--report-path -
Opinionated-csharp-todos is based on matching prefixes and suffixes using regular expressions. This logic is quite limiting and often you would like to further refine the checks and post-process the collected TODOs.
We provide two recipes to demonstrate how you can further use the JSON report downstream.
The script recipes/powershell/RenderBadge.ps1 uses https://shields.io to render the number of TODOs to SVG badges. If you include this script in your continuous integration, you can put up the badge to let the users know the state of the code base.
The script recipes/powershell/RenderTaskList.ps1 renders the TODOs as markdown grouped by the corresponding source files. By specifying an URL prefix it automatically links the location of the TODOs to the code base.
Thus you can use this task list for a rudimentary task management and navigate the TODOs.
Feature requests, bug reports etc. are highly welcome! Please submit a new issue.
If you want to contribute in code, please see CONTRIBUTING.md.
We follow Semantic Versioning. The version X.Y.Z indicates:
- X is the major version (backward-incompatible w.r.t. command-line arguments),
- Y is the minor version (backward-compatible), and
- Z is the patch version (backward-compatible bug fix).