todocheck is a static code analyzer for annotated TODO
comments.
It let's you create actionable TODOs
by annotating them with issues from any of the supported issue trackers.
No longer will you discover arcane, undocumented TODO
comments, scattered across your code base.
See How it works for more info.
- How it works
- Installation
- Quickstart
- Supported Issue Trackers
- Supported Programming Languages
- Ignored Files & Directories
- Custom todos
- Supported Output Formats
- Authentication
- Configuration
- Contributing
Here's an example of an annotated TODO
:
// TODO J123: Fix this typo
func fuu() {
...
}
In case the linked issue J123
is open, todocheck
will not report any error. In case it is closed or doesn't exist, todocheck will show an error:
ERROR: Issue is closed.
myproject/main.go:12: // TODO J123: Fix this typo
ERROR: Issue doesn't exist.
myproject/main.go:14: // TODO J321: A non-existent issue
If there is an unannotated TODO
in your code base, todocheck will also report it as a malformed TODO
:
ERROR: Malformed todo.
myproject/main.go:16: // TODO - This is not a valid annotated todo
Only TODO
s with valid, open issues are allowed to exist in the codebase.
By integrating todocheck in your development workflow & CI pipeline, you can ensure that there will be no half-baked issue closed with pending TODO
s in the codebase.
brew install preslavmihaylov/taps/todocheck
Download the binary for your OS from the latest release.
Optionally verify the sha256
checksum:
- For macos, run
shasum -a 256 <binary>
& verify it's the same as<binary>.sha256
- For linux, run
sha256sum <binary>
- For windows, use a SHA256 checksum utility
Afterwards, verify the shasum is the same as <binary>.sha256
.
Place the binary in a folder, shined upon by your $PATH
.
- For macos & linux, that's typically
/usr/local/bin/
First, you need to configure todocheck
's integration with your issue tracker.
This is done by creating a .todocheck.yaml
file in the root of your project.
For public github or gitlab repositories, you don't need to specify a config file, as long as you are using git, as todocheck
will interpret your issue tracker from the git configuration.
Alternatively, the explicit configuration for a public github repository would look like this:
origin: github.com/user/repository
issue_tracker: GITHUB
See Supported Issue Trackers for more issue tracker options.
After the config file is in place, simply run todocheck
from the root of your project.
In case you are running todocheck
from a different directory, you can specify your project's path using the --basepath
flag and the project configuration with --config
:
$ todocheck --basepath path/to/project --config path/to/config/.todocheck.yaml
If the --config
option is not specified, the configuration in the basepath will be used.
In the example above, it would look for it in path/to/project/.todocheck.yaml
.
Currently, todocheck supports the following issue trackers:
Issue Tracker | Description |
---|---|
Github | Both public & private repositories are supported |
Gitlab | Both public & private repositories are supported |
Jira | Supported via offline tokens |
Pivotal Tracker | Supported via an API token |
Redmine | Supports public access with no auth & private access via an API token |
To integrate with a public github repository, there's no need to provide a .todocheck.yaml
explicitly as it can automatically detect the issue tracker based on the git remote address.
And if you want to be explicit, please specify the origin of your repo and the GITHUB
issue tracker in your .todocheck.yaml
configuration:
origin: github.com/user/repository
issue_tracker: GITHUB
To integrate with a private github repository, you'll also need to specify the auth
section with the apitoken
type:
origin: github.com/user/repository
issue_tracker: GITHUB
auth:
type: apitoken
The first time you run the application, it will ask for your personal access token:
After you've specified it, it will store it in the auth tokens cache for subsequent executions. See the Authentication section for more info.
To integrate with a public gitlab repository, there's no need to provide a .todocheck.yaml
explicitly as it can automatically detect the issue tracker based on the git remote address.
And if you want to be explicit, please specify the origin of your repo and the GITLAB
issue tracker in your .todocheck.yaml
configuration:
origin: gitlab.com/user/repository
issue_tracker: GITLAB
To integrate with a private gitlab repository, you'll also need to specify the auth
section with the apitoken
type:
origin: github.com/user/repository
issue_tracker: GITLAB
auth:
type: apitoken
The first time you run the application, it will ask for your personal access token:
After you've specified it, it will store it in the auth tokens cache for subsequent executions. See the Authentication section for more info.
To integrate with your organization's Jira, you'll need to specify JIRA
as your issue tracker, the origin of your jira server instance, along with an offline token:
origin: https://myjira.awesomeorg.com
issue_tracker: JIRA
auth:
type: offline
offline_url: https://myjira.awesomeorg.com/offline
After you run todocheck for the first time, it will request your offline token:
After you've given the offline token to todocheck
's prompt, it will store it in the auth tokens cache for subsequent executions.
See the Authentication section for more info.
To integrate with a pivotal tracker project, specify the origin of your project and the PIVOTAL_TRACKER
issue tracker in your .todocheck.yaml
configuration.
You should also specify the apitoken
as an auth type:
origin: pivotaltracker.com/projects/PROJECT_ID
issue_tracker: PIVOTAL_TRACKER
auth:
type: apitoken
The first time you run the application, it will ask for your API Token.
After you've specified it, it will store it in the auth tokens cache for subsequent executions. See the Authentication section for more info.
To integrate with a redmine issue tracker project, specify the origin of your installation (without project path) and the REDMINE
issue tracker in your .todocheck.yaml
configuration.
You should also specify the apitoken
as an auth type if you have authentication enabled on your server:
origin: https://redmine.mycorp.com
issue_tracker: REDMINE
auth:
type: apitoken
Alternatively, if no authentication is required, don't include the auth
section.
The first time you run the application, it will ask for your API Token.
After you've specified it, it will store it in the auth tokens cache for subsequent executions. See the Authentication section for more info.
In order to integrate todocheck with your redmine server, you'll need to enable the server's rest API and, optionally, enable authentication - See Docs.
Currently, todocheck has parsers for three different types of comments:
- Standard comments like
//
and/* */
- Scripts using single-line comments
#
- Python with its
#
single-line and"""
multi-line comments
Based on this, here are the supported languages:
Supported Languages | Description |
---|---|
Bash/Zsh | *.sh/*.bash/*.zsh extension. Supports # single-line comments |
C | *.c extension. Supports single-line // comments and multi-line /* */ comments |
C++ | *.cpp extension. Supports single-line // comments and multi-line /* */ comments |
CSharp | *.cs extension. Supports single-line // comments and multi-line /* */ comments |
Golang | *.go extension. Supports single-line // comments and multi-line /* */ comments |
Groovy | *.groovy , *.gvy , *.gy , *.gsh extensions. Supports single-line // comments and multi-line /* */ comments |
Java | *.java extension. Supports single-line // comments and multi-line /* */ comments |
JavaScript/Typescript | *.js/*.ts extension. Supports single-line // comments and multi-line /* */ comments |
PHP | *.php extension. Supports single-line # and // comments and multi-line /* */ comments |
Python | *.py extension. Supports single-line # comments and multi-line """ comments |
R | *.R extension. Supports single-line // comments and multi-line /* */ comments |
Rust | *.rs extension. Supports single-line // comments and multi-line /* */ comments |
Scala | *.scala , *.sc extensions. Supports single-line // comments and multi-line /* */ comments |
Swift | *.swift extension. Supports single-line // comments and multi-line /* */ comments |
Vue | *.vue extension. Supports single-line // comments, multi-line /* */ comments and multi-line <!-- --> HTML comments |
If you don't see your favorite language in this table, but it does use one of the supported comment formats, submit an issue here
If you want certain project files not to be included for todocheck processing, you can specify that in an ignored
section in the .todocheck.yaml
configuration:
origin: some.origin.com
issue_tracker: JIRA
ignored:
- vendor-folder/
- scripts/*.sh
Ignored files/folders can be specified via standard pattern-matching.
Hidden files (dotfiles, i.e. .git
, .gitignore
, etc) are ignored by default.
By default, todocheck
looks for todos in the format // TODO 231: ...
Most projects stick to this format.
However, if you have some special todo format, which is different from the default one, you can specify a list of custom todo formats in your .todocheck.yaml
origin: some.origin.com
issue_tracker: JIRA
custom_todos:
- "@fix"
- ToDo
Note that this list adds additional formats the tool should match, but doesn't substitute the default one - TODO
.
With the above configuration, todocheck
will start matching todo comments in the following formats:
// @fix 234: a leftover task...
// ToDo 15: A funky-looking todo comment
Currently, todocheck supports two kinds of output - standard & json.
The standard format is meant to be user-friendly & used in the normal day-to-day workflow.
ERROR: Malformed todo
tmp/main.groovy:2: // TODO: Invalid todo
> TODO should match pattern - TODO {task_id}:
ERROR: Malformed todo
tmp/main.groovy:12: // TODO: Invalid todo
> TODO should match pattern - TODO {task_id}:
ERROR: Issue doesn't exist
tmp/main.groovy:15: // TODO 3: A non-existent issue
The json output is meant to be used for integrating todocheck in third-party systems, such as an IDE plugin.
To use json output, use the --format json
flag.
[
{
"type":"Malformed todo",
"filename":"tmp/main.groovy",
"line":2,
"message":"TODO should match pattern - TODO {task_id}:"
},
{
"type":"Malformed todo",
"filename":"tmp/main.groovy",
"line":12,
"message":"TODO should match pattern - TODO {task_id}:"
},
{
"type":"Issue doesn't exist",
"filename":"tmp/main.groovy",
"line":15,
"message":""
}
]
For public repositories, todocheck requires no authentication as the issues in the issue tracker are publicly available.
In this case, you need not specify any auth
section in your configuration or explicitly set it as none
:
origin: github.com/user/repository
issue_tracker: GITHUB
auth:
type: none
For private repositories, todocheck requires an authentication token which the user specifies via a secure prompt.
For github & gitlab, there is a personal access token one can get in his user settings & todocheck can use that to read your repository's issues. Github docs Gitlab docs
To use this authentication type, configure the auth type as apitoken
:
origin: github.com/user/repository
issue_tracker: GITHUB
auth:
type: apitoken
For Jira, you'll need to specify an offline token:
origin: https://myjira.awesomeorg.com
issue_tracker: JIRA
auth:
type: offline
offline_url: https://myjira.awesomeorg.com/offline
An offline token is one which your user can get by accessing a specific page, where your server generates an access token.
After you've received either an api token (github/gitlab) or an offline token, you can paste it in todocheck's secure prompt when asked.
Example with github PAT prompt:
Afterwards, todocheck will not ask for your token again as it will store it in its tokens cache.
Whenever a user grants todocheck an auth token, the token will be stored in a file ~/.todocheck/authtokens.yaml
.
If that file doesn't already exist, it will be created with read/write permissions for current user only (permission 0700
).
This file stores a key-value mapping of project origin to auth token.
Whenever todocheck runs, it first checks this file for an existing authentication token before contacting the issue tracker's server.
If you want to specify a different tokens cache, you can set the tokens_cache
section in your .todocheck.yaml
configuration:
# remainder omitted
auth:
# remainder omitted
tokens_cache: path/to/tokens_cache
If you need to pass an authentication token via an environment variable, use the TODOCHECK_AUTH_TOKEN
environment variable.
Example usage:
TODOCHECK_AUTH_TOKEN=<secret-token> todocheck --basepath path/to/project
This can be useful when you want to integrate todocheck in your CI pipeline.
In your .todocheck.yaml
configuration, you have the following configuration options:
- origin - the origin of your remote repository/issue tracker (example:
github.com/golang/go
) - issue_tracker - the issue tracker type you're using. Possible options -
GITHUB
,GITLAB
,JIRA
- ignored - a list of directories/files todocheck should ignore. Supports pattern-macthing, e.g.
*.sh
. - custom_todos - a list of custom todos variables.
TODO
will always be added. (example:"@fix"
) - auth - the authentication configuration for your issue tracker. If not present, it defaults to auth
type: none
- type - the type of authentication. Possible options -
none
(default),offline
,apitoken
A - offline_url - the url for fetching offline tokens. Only used when type is
offline
- tokens_cache - the location of your auth tokens cache. Defaults to
~/.todocheck/authtokens.yaml
- type - the type of authentication. Possible options -
In your tokens cache (default: ~/.todocheck/authtokens.yaml
), authentication tokens are stored in the following format:
tokens:
github.com/user1/repo1: SECRET_TOKEN_1
gitlab.com/user2/repo2: SECRET_TOKEN_2
https://jira.awesomeorg.com/offline: SECRET_TOKEN_3
If you'd like to explicitly specify an access token in this file, feel free to do so. This will let the user not have to manually input the token on the first todocheck execution.
This can be used e.g. in a CI environment, in an initial laptop setup script, etc.
Alternatively, use an Auth Token via Environment Variable
If you want to report an issue, make improvement suggestions or open a pull request, refer to the Contributing guide
Special thanks to all the project's contributors!