tatr README

The project's README from github.com/tsoding/tatr. As one markdown file: README.md.

Task Tracker

Cover by rexim

This is an improvised Tasks system, because I needed something more powerful than just plane TODOs in the Source Code of my projects, yet I didn't want to install a full blown Issue Tracker System.

The Spec

Layout

Each project at the root has tasks/ folder which contains sub-folders for each task.

project/
+-...
+-tasks/
| +-tags
| +-20260824-215300
| | +-TASK.md
| | +-...
| +-20260830-000403-rexim
| | +-TASK.md
| | +-screenshot.png
| | +-...
| +-...
+-...

HUID

Each task sub-folder is named with a Task ID. The Task ID format is [0-9]{8}-[0-9]{6}. Just grab the current date and time and use it as the Task ID. Use UTC timezone so the current timezone is irrelevant. If your Task ID collides with an existing one, just wait one second and try again.

The full format is actually [0-9]{8}-[0-9]{6}(-[a-zA-Z0-9\\-]*)?. So if you work in a team you can agree on unique suffixes per individual to slap at the end like 20260829-235855-rexim or 20260829-235902-01. Those are valid Task IDs too.

I call this ID system HUID (Human-Unique IDentifier). It is fairly unique if you generate IDs at "Human-speed". That is for me personally the speed at which I need to generate them is never below one second.

Having a Unique Task ID is beneficial under such control systems as git, because you can generate tasks in parallel branches and then relatively easily merge them together.

TASK.md

Inside of the task sub-folder there is one mandatory file TASK.md which is a markdown file describing the task. The folder may contain other files as attachments to the task. TASK.md should link to the attachments as necessary. Try to keep the size of the attachments small, since they are going to be committed to the git repo. Use ffmpeg to reencode any screencast to reduce their size as necessary.

The format of TASK.md:

# <title>

- STATUS: (OPEN|CLOSED)
- PRIORITY: <number>
- TAGS: <comma-and-whitespace-separated-list-of-tags>

[description]

The STATUS property defines whether the task is done or not. There could be only two statuses. If you need more it is generally recommended to use TAGS for whatever you are trying to do.

The PRIORITY is generally used for sorting the tasks by the external tools. One thing I've seen people online do is stressing out about what priority to put. Don't think of priority as an absolute value. Think of it as the means of getting your list of tasks sorted in a specific way you want them to see.

The TAGS property contains the list of tags separated by commas and whitespaces. TAGS: foo,bar,baz defines 3 tags. TAGS: foo, hello world also defines 3 tags. You can use these tags to group tasks into categories. Like bug or enhancement.

As you work on the task feel free to append any discovered details about the task to the description.

Use git-blame and git-log to learn about when, how and by whom any changes to the task were made.

Tag descriptions

There might be an optional tasks/tags file with the following format:

<tag-name> [,] <tag-description>
<tag-name> [,] <tag-description>
<tag-name> [,] <tag-description>
...

It serves as a documentation for each existing tag and the thirdparty tools may use it to display the tag descriptions.

The Tool

The repo comes with a command line tool that helps to navigate and manipulate the tasks/ folder:

$ cc -o nob nob.c
$ ./nob
$ sudo cp ./build/tatr /usr/local/bin/
$ tatr help

It is specifically optimized to be run in compilation mode of Emacs. Not sure how useful it is outside of this use case.

We only support Linux right now But I have tasks to add Windows and MacOS support in the future.

You are welcome to make your own tools.

Tatr Query Language (TQL)

The Query language that is used in tatr ls command to select a set of tasks.

Examples

Query everything with tag bug:

$ tatr ls :bug

Everything with tag bug, but without tag ui:

$ tatr ls :bug and not :ui

Everything that is not tagged:

$ tatr ls not tagged

All the bugs with priority less than 50:

$ tatr ls :bug and priority lt 50

Syntax

Here is the Backus–Naur form of the language:

<expr>            ::= <or>
<or>              ::= <and> *('or' <and>)
<and>             ::= <compare> *('and' <compare>)
<compare>         ::= <primary> *(<compare-op> <primary>)
<compare-op>      ::= 'lt' | 'le' | 'gt' | 'ge' | 'eq' | 'ne'
<primary>         ::= <tag>
                    | '[' <expr> ']'
                    | 'not' <primary>
                    | 'any'
                    | 'tagged'
                    | 'priority'
                    | <number>
<tag>             ::= ':' 1*<any-character-except-whitespaces-and-square-brackets>
<number>          ::= ['-'] 1*<digit>

The syntax is designed to be used in shell environment without requiring any special escaping.

In shells parenthsis usually have special meaning. Because of that we use square brackets for grouping expressions '[' <expr> ']'.

Another problematic symbols are < and >, which are usually used for file redirecting. Which means we can't easily use traditional comparison operators. So we are following the test(1) utility convention: lt, le, gt, ge, eq, and ne.

Since brackets have a special meaning in TQL, if you have any tags that contain them, you probably won't be able to filter by them (even though the specs do not explicitly prohibit square brackets in the tags). Just don't use square brackets in the tags if you are using tatr I guess. I may do something about that later.

Reference

Expression Description
<a> or <b> True when <a> or <b> or both are true. Just a regular logical disjunction.
<a> and <b> True when both <a> and <b> are true. Just a regular logical conjunction.
:<tag> True when a task's TAGS property contains <tag>.
not <expr> True when <expr> is false.
tagged True when a task has at least one tag in its TAGS property.
any Always true for any task.
priority Priority of the task as an integer.
<a> lt <b> True when <a> is less than <b>.
<a> gt <b> True when <a> is greater than <b>.
<a> le <b> True when <a> is less or equal to <b>.
<a> ge <b> True when <a> is greater or equal to <b>.
<a> eq <b> True when <a> is equal to <b>.
<a> ne <b> True when <a> is not equal to <b>.

The License

All the code in this repo is released under GNU General Public License, version 2 license unless stated otherwise (specifically, the files in ./thirdparty/ folder have their own corresponding licenses)

The cover art in the ./cover/ folder is under the CC BY-NC.

tatr (tsoding/tatr)

Searching Database…

450 ·GitHub
这是什么?Tatr 是一个轻量、对 git 友好的任务追踪器,把每个任务存成 tasks/ 文件夹里的纯 Markdown 文件,而不需要一整套工单跟踪系统。
这是图形界面应用,还是只是一种文件约定?它主要是一种规范:任务以“tasks/ /TASK.md”文件的形式直接提交进 git,另外还配有一个小型命令行工具(tatr)用于查询和操作这些文件。
怎么用它开始追踪任务?在项目根目录创建 tasks/ 文件夹,然后为每个新任务添加一个以 HUID 命名(当前 UTC 日期+时间,例如 20260829-235855)的子文件夹,里面放一个带有 STATUS、PRIORITY 和 TAGS 属性的 TASK.md 文件。
必须用 tatr 命令行工具,还是只用纯文件就行?仓库自带一个小型命令行工具(tatr)用于浏览和查询 tasks/ 文件夹,但由于每个任务只是一个放了 Markdown 文件的文件夹,你也可以只用 git 和文本编辑器来管理。
tatr 命令行工具能在我的操作系统上运行吗?目前 tatr 工具只支持 Linux;Windows 和 macOS 支持已在计划中,但尚未实现。
许可证简单明了么?代码以 GPLv2 发布(第三方文件除外,它们保留各自的许可证),但仓库里的封面图另行以 CC BY-NC 授权。
什么是 HUID?它是 Tatr 的“人类唯一标识符”格式 YYYYMMDD-HHMMSS(可选加后缀),由当前 UTC 时间生成,因此在并行 git 分支里创建的任务 ID 很少冲突,能够干净地合并。
什么是 TQL?TQL(Tatr Query Language)由“tatr ls”命令使用,按标签和优先级过滤任务,用方括号分组,并采用 lt、gt、eq 这类 test(1) 风格的运算符而不是符号,以保证 shell 安全。
为什么不直接用常规的工单系统?作者想要比源码里的普通 TODO 注释更强大、又比安装一整套工单跟踪系统更轻量的东西,于是任务就以带版本控制的 Markdown 文件形式直接存放在 git 仓库里。
它和编辑器有集成吗?它专门针对 Emacs 的 compilation mode 做了优化,不过任何人都可以在同样的 tasks/ 文件夹格式之上构建自己的工具。
What are similar projects?epiq, git, diff-so-fancy, difftastic, cz-cli, git-filter-repo, lane, tig
Creator
tsoding
Size
0.9 MB
Stars
450
Updated
CommitOct 18
Age
1mo
Commits · 90 Days