simple-project-tracker 1.0.4__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simple_project_tracker-1.0.4/simple_project_tracker.egg-info → simple_project_tracker-1.2.0}/PKG-INFO +98 -23
- simple_project_tracker-1.2.0/README.md +217 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/pyproject.toml +33 -35
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0/simple_project_tracker.egg-info}/PKG-INFO +98 -23
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/simple_project_tracker.egg-info/SOURCES.txt +14 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_cli.py +3 -3
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_commands.py +4 -5
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_daemon.py +83 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_details.py +2 -4
- simple_project_tracker-1.2.0/tests/test_doctor.py +200 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_frecency.py +1 -2
- simple_project_tracker-1.2.0/tests/test_identity.py +199 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_keys.py +21 -1
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_labels.py +2 -3
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_moves.py +3 -4
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_names.py +0 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_paths.py +0 -1
- simple_project_tracker-1.2.0/tests/test_portable.py +190 -0
- simple_project_tracker-1.2.0/tests/test_relocate.py +201 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_render.py +1 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_selection.py +59 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_settings.py +66 -3
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_storage.py +1 -3
- simple_project_tracker-1.2.0/tests/test_todos.py +778 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_undo.py +3 -4
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_view.py +1 -4
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/cli/app.py +31 -7
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/cli/commands.py +157 -453
- simple_project_tracker-1.2.0/tracker/cli/doctor.py +613 -0
- simple_project_tracker-1.2.0/tracker/cli/entries.py +560 -0
- simple_project_tracker-1.2.0/tracker/cli/relocate.py +245 -0
- simple_project_tracker-1.2.0/tracker/cli/todo.py +404 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/defaults.py +44 -1
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/keys.py +19 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/paths.py +18 -1
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/settings.py +67 -8
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/writer.py +3 -6
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/daemon.py +38 -17
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/discovery.py +9 -7
- simple_project_tracker-1.0.4/tracker/core/selection.py → simple_project_tracker-1.2.0/tracker/core/entries.py +186 -215
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/frecency.py +0 -1
- simple_project_tracker-1.2.0/tracker/core/identity.py +340 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/inspect.py +13 -14
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/models.py +26 -3
- simple_project_tracker-1.2.0/tracker/core/portable.py +185 -0
- simple_project_tracker-1.2.0/tracker/core/selection.py +248 -0
- simple_project_tracker-1.2.0/tracker/core/storage.py +86 -0
- simple_project_tracker-1.2.0/tracker/core/todos.py +358 -0
- simple_project_tracker-1.2.0/tracker/core/undo.py +96 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/view.py +26 -16
- simple_project_tracker-1.2.0/tracker/share/completion.bash +7 -0
- simple_project_tracker-1.2.0/tracker/share/completion.zsh +13 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/share/help.txt +242 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/share/settings.toml +96 -28
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/ui/ansi.py +0 -1
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/ui/details.py +18 -4
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/ui/help.py +8 -2
- simple_project_tracker-1.2.0/tracker/ui/mentions.py +194 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/ui/render.py +160 -93
- simple_project_tracker-1.2.0/tracker/ui/todos.py +363 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/util/compat.py +1 -2
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/util/files.py +3 -5
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/util/text.py +0 -1
- simple_project_tracker-1.0.4/README.md +0 -142
- simple_project_tracker-1.0.4/tracker/core/identity.py +0 -140
- simple_project_tracker-1.0.4/tracker/core/storage.py +0 -59
- simple_project_tracker-1.0.4/tracker/core/undo.py +0 -63
- simple_project_tracker-1.0.4/tracker/share/completion.bash +0 -7
- simple_project_tracker-1.0.4/tracker/share/completion.zsh +0 -13
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/LICENSE +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/setup.cfg +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/simple_project_tracker.egg-info/dependency_links.txt +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/simple_project_tracker.egg-info/entry_points.txt +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/simple_project_tracker.egg-info/top_level.txt +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tests/test_help.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/__init__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/__main__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/cli/__init__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/__init__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/config/metadata.py +1 -1
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/__init__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/core/labels.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/py.typed +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/share/completion.fish +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/ui/__init__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/ui/ask.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/util/__init__.py +0 -0
- {simple_project_tracker-1.0.4 → simple_project_tracker-1.2.0}/tracker/util/unknown.py +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple-project-tracker
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Simple project tracker
|
|
5
5
|
Author-email: MattFor <mattfor@relaxy.xyz>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -50,7 +50,9 @@ TID | ID | NAME | STATUS | LAST TOUCHED | NOTE
|
|
|
50
50
|
|
|
51
51
|
- [Install](#install)
|
|
52
52
|
- [Commands](#commands)
|
|
53
|
+
- [Todos](#todos)
|
|
53
54
|
- [Selecting projects](#selecting-projects)
|
|
55
|
+
- [Several machines](#several-machines)
|
|
54
56
|
- [Configuration](#configuration)
|
|
55
57
|
- [Development](#development)
|
|
56
58
|
- [License](#license)
|
|
@@ -68,23 +70,27 @@ Python 3.11+. Then `t init ~/(your project directory)` to fill the database.
|
|
|
68
70
|
|
|
69
71
|
## Commands
|
|
70
72
|
|
|
71
|
-
| Command | Aliases
|
|
72
|
-
|
|
73
|
-
| `list` | `l`, `ls`
|
|
74
|
-
| `check` | `c`, `cc`, `info`
|
|
75
|
-
| `add` | `a`
|
|
76
|
-
| `remove` | `rm`, `r`, `del`
|
|
77
|
-
| `forget` | `ignore`
|
|
78
|
-
| `edit` | `e`
|
|
79
|
-
| `note` | `n`, `sn`
|
|
80
|
-
| `status` | `st`, `ss`
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
73
|
+
| Command | Aliases | What it does |
|
|
74
|
+
| ------------ | ------------------- | -------------------------------------------------------------------- |
|
|
75
|
+
| `list` | `l`, `ls` | List projects, with search, regex, filters and setting overrides |
|
|
76
|
+
| `check` | `c`, `cc`, `info` | Everything about a project: git state, size, language, version, note |
|
|
77
|
+
| `add` | `a` | Track a project, or scan a directory and track what is inside |
|
|
78
|
+
| `remove` | `rm`, `r`, `del` | Stop tracking projects (files untouched) |
|
|
79
|
+
| `forget` | `ignore` | Stop tracking and keep scans from finding it again |
|
|
80
|
+
| `edit` | `e` | Change a `status` or a `note` |
|
|
81
|
+
| `note` | `n`, `sn` | Set a note without naming the field |
|
|
82
|
+
| `status` | `st`, `ss` | List statuses, set one, or move every project from one to another |
|
|
83
|
+
| `todo` | `td`, `todos` | A todo list of its own: add, edit, status, note, done, clear |
|
|
84
|
+
| `init` | `i`, `scan` | Scan a directory and merge the result into the database |
|
|
85
|
+
| `path` | `p`, `where` | Print a project's path, e.g. `cd "$(t path tracker)"` |
|
|
86
|
+
| `undo` | `u`, `revert` | Take back the last change, undo again to put it back |
|
|
87
|
+
| `move` | `mv` | Move the settings, database or todo list, and point tracker at it |
|
|
88
|
+
| `stats` | `summary` | Totals, a breakdown by status, most and least recently touched |
|
|
89
|
+
| `settings` | `s`, `config` | Show, edit, get or set the configuration |
|
|
90
|
+
| `doctor` | `hc`, `health` | Report what is wrong with the database |
|
|
91
|
+
| `fix` | `repair`, `migrate` | Repair everything `doctor` found |
|
|
92
|
+
| `completion` | | Print a shell completion script for bash, zsh or fish |
|
|
93
|
+
| `daemon` | `d`, `bg` | `start`, `stop`, `restart`, `status`, `log`, `run` |
|
|
88
94
|
|
|
89
95
|
The project goes before or after the command, whichever reads better, and a command fuses
|
|
90
96
|
with its own action:
|
|
@@ -107,10 +113,40 @@ t all # everything with no limit and no filter
|
|
|
107
113
|
For more information do: `t help`, `t help <command>` or `t help <topic>`. The full guide
|
|
108
114
|
is within `man tracker`.
|
|
109
115
|
|
|
116
|
+
## Todos
|
|
117
|
+
|
|
118
|
+
List of notes that's separate from the main project database.
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
t td # the whole list
|
|
122
|
+
t td add write the changelog # the rest of the line is the name
|
|
123
|
+
t td 3 done # also: t td done 3
|
|
124
|
+
t td 3 st blocked # any status you like
|
|
125
|
+
t td 3 n waiting on review # and a note under it
|
|
126
|
+
t td list s:todo # only what is still open
|
|
127
|
+
t td clear # drop every finished one
|
|
128
|
+
t td undo # take the last change back
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
TID | ID | NAME | STATUS | CREATED | NOTE
|
|
133
|
+
--- | -- | --------------------- | ------- | ---------- | ----------------------
|
|
134
|
+
1 | 1 | write the changelog | todo | 2m ago | blocked on the release
|
|
135
|
+
2 | 2 | fix the daemon logs | done | 1h ago
|
|
136
|
+
3 | 3 | ship the todo feature | review | 1h ago | shipped on a sunday
|
|
137
|
+
3 todos, 2 left (2 todo, 1 done)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
A todo is selected exactly the same way a project is, and the same short forms apply.
|
|
141
|
+
|
|
142
|
+
A note may point at a project with `@name`, printed as `name#id:tid` in that project's
|
|
143
|
+
status colour. `t check <project>` then lists the todos about it, and `t td check <todo>`
|
|
144
|
+
the projects it names.
|
|
145
|
+
|
|
110
146
|
## Selecting projects
|
|
111
147
|
|
|
112
148
|
| Selector | Means |
|
|
113
|
-
|
|
149
|
+
| ----------- | --------------------------------------------------------- |
|
|
114
150
|
| `12` | ID or TID 12 |
|
|
115
151
|
| `i:12` | The permanent ID, `id:` and `#12` too |
|
|
116
152
|
| `t:12` | The temporary ID, `tid:`, `@12` and `:12` too |
|
|
@@ -124,6 +160,39 @@ A temporary ID is the index of the latest output.
|
|
|
124
160
|
When a partial name matches several projects, it's settled by
|
|
125
161
|
`projects.conflict_resolution_preference`.
|
|
126
162
|
|
|
163
|
+
## Several machines
|
|
164
|
+
|
|
165
|
+
The database can live in a Syncthing, Dropbox or git folder.
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
t mv db ~/sync-folder/data.pkl # put the database where it syncs
|
|
169
|
+
t doctor # what is wrong with it
|
|
170
|
+
t fix # put that right, undoable
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```toml
|
|
174
|
+
[sync.roots]
|
|
175
|
+
media = "/archives/media" # stored as @media/photos, wherever media points
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Roots belonging to one machine alone go in `~/.config/tracker/roots.toml`, which holds the
|
|
179
|
+
same table and stays out of whatever syncs the settings.
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
$ t doctor
|
|
183
|
+
|
|
184
|
+
Tracked twice (2)
|
|
185
|
+
one project under two entries, the older one pointing at a path that is gone
|
|
186
|
+
|
|
187
|
+
von-neumann-machine-simulator #3 -> #61, by fingerprint
|
|
188
|
+
gone ~/Programming/Development/Rust/von-neumann-machine-simulator
|
|
189
|
+
here ~/programming/development/rust/von-neumann-machine-simulator
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`fix` keeps the older entry's ID, status and note and the living entry's path and
|
|
193
|
+
timestamp. Two different notes are joined rather than one being dropped, and `t undo`
|
|
194
|
+
takes the whole repair back.
|
|
195
|
+
|
|
127
196
|
## Configuration
|
|
128
197
|
|
|
129
198
|
```sh
|
|
@@ -138,7 +207,7 @@ or by its initials, with the section shortening the same way: `display.list_limi
|
|
|
138
207
|
`list_limit`, `list_lim`, `l_l`, `ll`, `d.ll`. Ambiguities are reported.
|
|
139
208
|
|
|
140
209
|
| Setting | What it does |
|
|
141
|
-
|
|
210
|
+
| ----------------------------------- | ----------------------------------------------------------- |
|
|
142
211
|
| `display.filter` | Filters every listing but `all`, e.g. `["-s:archive"]` |
|
|
143
212
|
| `display.columns`, `display.format` | Which columns, or a row layout of your own |
|
|
144
213
|
| `display.relative_times` | `2 days ago` instead of a timestamp |
|
|
@@ -148,6 +217,10 @@ or by its initials, with the section shortening the same way: `display.list_limi
|
|
|
148
217
|
| `projects.auto_status` | Status from how long ago a project was touched |
|
|
149
218
|
| `scan.detect_moves` | A moved project keeps its entry instead of looking deleted |
|
|
150
219
|
| `daemon.paths`, `daemon.interval` | What the background scanner watches, and how often |
|
|
220
|
+
| `sync.portable_paths`, `sync.roots` | Paths a database shared between machines can be read with |
|
|
221
|
+
| `todos.new_status`, `.done_status` | What a new todo is called, and what `done` and `clear` use |
|
|
222
|
+
| `todos.sort`, `todos.newest_first` | How the todo list is ordered |
|
|
223
|
+
| `[todos.display]` | Display settings the todo list alone uses |
|
|
151
224
|
|
|
152
225
|
Notes can colour themselves: `t note 12 {red}broken{/} since friday`.
|
|
153
226
|
|
|
@@ -162,13 +235,15 @@ make check # format, lint, types and tests (what CI runs)
|
|
|
162
235
|
|
|
163
236
|
LLMs were used to:
|
|
164
237
|
|
|
165
|
-
- write
|
|
238
|
+
- write tests
|
|
166
239
|
- write the man page
|
|
240
|
+
- write the help section
|
|
167
241
|
- check for critical issues and annotation errors
|
|
168
242
|
|
|
169
|
-
HOWEVER
|
|
243
|
+
**HOWEVER**, the output was then manually reviewed and issues were fixed by a human.
|
|
244
|
+
I wanted to get this project out asap as I really needed it :P
|
|
170
245
|
|
|
171
246
|
## License
|
|
172
247
|
|
|
173
|
-
MIT [LICENSE](LICENSE).
|
|
248
|
+
MIT [LICENSE](LICENSE).
|
|
174
249
|
By MattFor.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# simple-project-tracker
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
A simple, but very customizable tracker to keep track of your projects, their states and
|
|
7
|
+
your notes on them.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
TID | ID | NAME | STATUS | LAST TOUCHED | NOTE
|
|
11
|
+
--- | -- | ----------------------------- | ------- | ------------ | ---------------------
|
|
12
|
+
1 | 8 | tracker | dev | 1m ago | release 1.0.0 today
|
|
13
|
+
2 | 3 | von-neumann-machine-simulator | dev | 23m ago | review saturday
|
|
14
|
+
3 | 26 | discord-profile-studio | stable | 1h ago
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Contents
|
|
18
|
+
|
|
19
|
+
- [Install](#install)
|
|
20
|
+
- [Commands](#commands)
|
|
21
|
+
- [Todos](#todos)
|
|
22
|
+
- [Selecting projects](#selecting-projects)
|
|
23
|
+
- [Several machines](#several-machines)
|
|
24
|
+
- [Configuration](#configuration)
|
|
25
|
+
- [Development](#development)
|
|
26
|
+
- [License](#license)
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
./install.sh # ~/.local
|
|
32
|
+
sudo ./install.sh # /usr/local
|
|
33
|
+
./install.sh --daemon # also install the daemon autostart entry
|
|
34
|
+
./install.sh --uninstall
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Python 3.11+. Then `t init ~/(your project directory)` to fill the database.
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
| Command | Aliases | What it does |
|
|
42
|
+
| ------------ | ------------------- | -------------------------------------------------------------------- |
|
|
43
|
+
| `list` | `l`, `ls` | List projects, with search, regex, filters and setting overrides |
|
|
44
|
+
| `check` | `c`, `cc`, `info` | Everything about a project: git state, size, language, version, note |
|
|
45
|
+
| `add` | `a` | Track a project, or scan a directory and track what is inside |
|
|
46
|
+
| `remove` | `rm`, `r`, `del` | Stop tracking projects (files untouched) |
|
|
47
|
+
| `forget` | `ignore` | Stop tracking and keep scans from finding it again |
|
|
48
|
+
| `edit` | `e` | Change a `status` or a `note` |
|
|
49
|
+
| `note` | `n`, `sn` | Set a note without naming the field |
|
|
50
|
+
| `status` | `st`, `ss` | List statuses, set one, or move every project from one to another |
|
|
51
|
+
| `todo` | `td`, `todos` | A todo list of its own: add, edit, status, note, done, clear |
|
|
52
|
+
| `init` | `i`, `scan` | Scan a directory and merge the result into the database |
|
|
53
|
+
| `path` | `p`, `where` | Print a project's path, e.g. `cd "$(t path tracker)"` |
|
|
54
|
+
| `undo` | `u`, `revert` | Take back the last change, undo again to put it back |
|
|
55
|
+
| `move` | `mv` | Move the settings, database or todo list, and point tracker at it |
|
|
56
|
+
| `stats` | `summary` | Totals, a breakdown by status, most and least recently touched |
|
|
57
|
+
| `settings` | `s`, `config` | Show, edit, get or set the configuration |
|
|
58
|
+
| `doctor` | `hc`, `health` | Report what is wrong with the database |
|
|
59
|
+
| `fix` | `repair`, `migrate` | Repair everything `doctor` found |
|
|
60
|
+
| `completion` | | Print a shell completion script for bash, zsh or fish |
|
|
61
|
+
| `daemon` | `d`, `bg` | `start`, `stop`, `restart`, `status`, `log`, `run` |
|
|
62
|
+
|
|
63
|
+
The project goes before or after the command, whichever reads better, and a command fuses
|
|
64
|
+
with its own action:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
t 12 es blocked # edit status also: t edit 12 status blocked
|
|
68
|
+
t 12 sn review sunday # set note also: t note 12 review sunday
|
|
69
|
+
t dst # daemon status
|
|
70
|
+
t sset ll 30 # settings set display.list_limit 30
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
A bare word defaults to a project lookup.
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
t tra # the check view for tracker
|
|
77
|
+
t stable # nothing is called that, so every stable project
|
|
78
|
+
t all # everything with no limit and no filter
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For more information do: `t help`, `t help <command>` or `t help <topic>`. The full guide
|
|
82
|
+
is within `man tracker`.
|
|
83
|
+
|
|
84
|
+
## Todos
|
|
85
|
+
|
|
86
|
+
List of notes that's separate from the main project database.
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
t td # the whole list
|
|
90
|
+
t td add write the changelog # the rest of the line is the name
|
|
91
|
+
t td 3 done # also: t td done 3
|
|
92
|
+
t td 3 st blocked # any status you like
|
|
93
|
+
t td 3 n waiting on review # and a note under it
|
|
94
|
+
t td list s:todo # only what is still open
|
|
95
|
+
t td clear # drop every finished one
|
|
96
|
+
t td undo # take the last change back
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
TID | ID | NAME | STATUS | CREATED | NOTE
|
|
101
|
+
--- | -- | --------------------- | ------- | ---------- | ----------------------
|
|
102
|
+
1 | 1 | write the changelog | todo | 2m ago | blocked on the release
|
|
103
|
+
2 | 2 | fix the daemon logs | done | 1h ago
|
|
104
|
+
3 | 3 | ship the todo feature | review | 1h ago | shipped on a sunday
|
|
105
|
+
3 todos, 2 left (2 todo, 1 done)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A todo is selected exactly the same way a project is, and the same short forms apply.
|
|
109
|
+
|
|
110
|
+
A note may point at a project with `@name`, printed as `name#id:tid` in that project's
|
|
111
|
+
status colour. `t check <project>` then lists the todos about it, and `t td check <todo>`
|
|
112
|
+
the projects it names.
|
|
113
|
+
|
|
114
|
+
## Selecting projects
|
|
115
|
+
|
|
116
|
+
| Selector | Means |
|
|
117
|
+
| ----------- | --------------------------------------------------------- |
|
|
118
|
+
| `12` | ID or TID 12 |
|
|
119
|
+
| `i:12` | The permanent ID, `id:` and `#12` too |
|
|
120
|
+
| `t:12` | The temporary ID, `tid:`, `@12` and `:12` too |
|
|
121
|
+
| `3-7`,`5+3` | A range, either direction, or a project and the next few |
|
|
122
|
+
| `s:blocked` | Every project with that status, `st:` and `status:` too |
|
|
123
|
+
| `name` | Exact or partial name, or a path, tab completion included |
|
|
124
|
+
| `all` | Every tracked project limits and display filters off |
|
|
125
|
+
|
|
126
|
+
A temporary ID is the index of the latest output.
|
|
127
|
+
|
|
128
|
+
When a partial name matches several projects, it's settled by
|
|
129
|
+
`projects.conflict_resolution_preference`.
|
|
130
|
+
|
|
131
|
+
## Several machines
|
|
132
|
+
|
|
133
|
+
The database can live in a Syncthing, Dropbox or git folder.
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
t mv db ~/sync-folder/data.pkl # put the database where it syncs
|
|
137
|
+
t doctor # what is wrong with it
|
|
138
|
+
t fix # put that right, undoable
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```toml
|
|
142
|
+
[sync.roots]
|
|
143
|
+
media = "/archives/media" # stored as @media/photos, wherever media points
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Roots belonging to one machine alone go in `~/.config/tracker/roots.toml`, which holds the
|
|
147
|
+
same table and stays out of whatever syncs the settings.
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
$ t doctor
|
|
151
|
+
|
|
152
|
+
Tracked twice (2)
|
|
153
|
+
one project under two entries, the older one pointing at a path that is gone
|
|
154
|
+
|
|
155
|
+
von-neumann-machine-simulator #3 -> #61, by fingerprint
|
|
156
|
+
gone ~/Programming/Development/Rust/von-neumann-machine-simulator
|
|
157
|
+
here ~/programming/development/rust/von-neumann-machine-simulator
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`fix` keeps the older entry's ID, status and note and the living entry's path and
|
|
161
|
+
timestamp. Two different notes are joined rather than one being dropped, and `t undo`
|
|
162
|
+
takes the whole repair back.
|
|
163
|
+
|
|
164
|
+
## Configuration
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
t settings # everything (default deviations marked)
|
|
168
|
+
t settings edit # open in $EDITOR
|
|
169
|
+
t sset list_limit 30 # rewrites that one line
|
|
170
|
+
t list ll=5 rt=true # override for one command only
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
A setting can be named in full, by its bare name, by a prefix, by the start of every word
|
|
174
|
+
or by its initials, with the section shortening the same way: `display.list_limit`,
|
|
175
|
+
`list_limit`, `list_lim`, `l_l`, `ll`, `d.ll`. Ambiguities are reported.
|
|
176
|
+
|
|
177
|
+
| Setting | What it does |
|
|
178
|
+
| ----------------------------------- | ----------------------------------------------------------- |
|
|
179
|
+
| `display.filter` | Filters every listing but `all`, e.g. `["-s:archive"]` |
|
|
180
|
+
| `display.columns`, `display.format` | Which columns, or a row layout of your own |
|
|
181
|
+
| `display.relative_times` | `2 days ago` instead of a timestamp |
|
|
182
|
+
| `display.name_max_width` | Shorten long names, `truncate` or `abbreviate` |
|
|
183
|
+
| `sorting.by`, `sorting.direction` | `last_touched`, `last_used`, `name`, `status`, `id`, `path` |
|
|
184
|
+
| `projects.ignore`, `.ignore_files` | Directories and files that never count as your own work |
|
|
185
|
+
| `projects.auto_status` | Status from how long ago a project was touched |
|
|
186
|
+
| `scan.detect_moves` | A moved project keeps its entry instead of looking deleted |
|
|
187
|
+
| `daemon.paths`, `daemon.interval` | What the background scanner watches, and how often |
|
|
188
|
+
| `sync.portable_paths`, `sync.roots` | Paths a database shared between machines can be read with |
|
|
189
|
+
| `todos.new_status`, `.done_status` | What a new todo is called, and what `done` and `clear` use |
|
|
190
|
+
| `todos.sort`, `todos.newest_first` | How the todo list is ordered |
|
|
191
|
+
| `[todos.display]` | Display settings the todo list alone uses |
|
|
192
|
+
|
|
193
|
+
Notes can colour themselves: `t note 12 {red}broken{/} since friday`.
|
|
194
|
+
|
|
195
|
+
## Development
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
make dev # editable install plus ruff, basedpyright, pytest
|
|
199
|
+
make check # format, lint, types and tests (what CI runs)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Disclosure
|
|
203
|
+
|
|
204
|
+
LLMs were used to:
|
|
205
|
+
|
|
206
|
+
- write tests
|
|
207
|
+
- write the man page
|
|
208
|
+
- write the help section
|
|
209
|
+
- check for critical issues and annotation errors
|
|
210
|
+
|
|
211
|
+
**HOWEVER**, the output was then manually reviewed and issues were fixed by a human.
|
|
212
|
+
I wanted to get this project out asap as I really needed it :P
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT [LICENSE](LICENSE).
|
|
217
|
+
By MattFor.
|
|
@@ -4,35 +4,33 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simple-project-tracker"
|
|
7
|
-
version = "1.0
|
|
7
|
+
version = "1.2.0"
|
|
8
8
|
description = "Simple project tracker"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
keywords = ["cli", "projects", "git", "tracker"]
|
|
12
12
|
|
|
13
|
-
authors = [
|
|
14
|
-
{ name = "MattFor", email = "mattfor@relaxy.xyz" }
|
|
15
|
-
]
|
|
13
|
+
authors = [{ name = "MattFor", email = "mattfor@relaxy.xyz" }]
|
|
16
14
|
|
|
17
15
|
license = "MIT"
|
|
18
16
|
license-files = ["LICENSE"]
|
|
19
17
|
|
|
20
18
|
classifiers = [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
"Development Status :: 4 - Beta",
|
|
20
|
+
"Environment :: Console",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
"Natural Language :: English",
|
|
23
|
+
"Operating System :: POSIX :: Linux",
|
|
24
|
+
"Operating System :: MacOS :: MacOS X",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Programming Language :: Python :: 3.13",
|
|
29
|
+
"Programming Language :: Python :: 3.14",
|
|
30
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
31
|
+
"Topic :: Software Development",
|
|
32
|
+
"Topic :: Utilities",
|
|
33
|
+
"Typing :: Typed",
|
|
36
34
|
]
|
|
37
35
|
|
|
38
36
|
dependencies = []
|
|
@@ -56,11 +54,7 @@ include = ["tracker*"]
|
|
|
56
54
|
tracker = ["py.typed", "share/*.toml", "share/*.txt", "share/completion.*"]
|
|
57
55
|
|
|
58
56
|
[dependency-groups]
|
|
59
|
-
dev = [
|
|
60
|
-
"ruff",
|
|
61
|
-
"basedpyright",
|
|
62
|
-
"pytest>=9.0.2"
|
|
63
|
-
]
|
|
57
|
+
dev = ["ruff", "basedpyright", "pytest>=9.0.2"]
|
|
64
58
|
|
|
65
59
|
[tool.ruff]
|
|
66
60
|
line-length = 90
|
|
@@ -74,17 +68,20 @@ skip-magic-trailing-comma = false
|
|
|
74
68
|
|
|
75
69
|
[tool.ruff.lint]
|
|
76
70
|
select = [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
71
|
+
"E4",
|
|
72
|
+
"E7",
|
|
73
|
+
"E9", # pycodestyle: real mistakes, not whitespace taste
|
|
74
|
+
"F", # pyflakes
|
|
75
|
+
"B", # bugbear
|
|
76
|
+
"C4", # comprehensions
|
|
77
|
+
"PIE", # misc lint
|
|
78
|
+
"SIM", # simplify
|
|
79
|
+
"UP", # pyupgrade
|
|
80
|
+
"ARG", # unused arguments
|
|
81
|
+
"PLE",
|
|
82
|
+
"PLW", # pylint errors and warnings
|
|
83
|
+
"FURB", # modernisation
|
|
84
|
+
"RUF", # ruff specific
|
|
88
85
|
]
|
|
89
86
|
|
|
90
87
|
[tool.ruff.lint.pycodestyle]
|
|
@@ -105,6 +102,7 @@ reportAny = false
|
|
|
105
102
|
reportExplicitAny = false
|
|
106
103
|
reportPrivateUsage = false
|
|
107
104
|
reportImportCycles = false
|
|
105
|
+
reportImplicitOverride = false
|
|
108
106
|
reportUnknownMemberType = false
|
|
109
107
|
reportUnknownArgumentType = false
|
|
110
108
|
reportUnknownVariableType = false
|