easydone 0.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.
- easydone-0.2.0/LICENSE +21 -0
- easydone-0.2.0/PKG-INFO +270 -0
- easydone-0.2.0/README.md +232 -0
- easydone-0.2.0/easydone/__init__.py +8 -0
- easydone-0.2.0/easydone/__main__.py +25 -0
- easydone-0.2.0/easydone/cli.py +155 -0
- easydone-0.2.0/easydone/format.py +164 -0
- easydone-0.2.0/easydone/logic.py +94 -0
- easydone-0.2.0/easydone/storage.py +178 -0
- easydone-0.2.0/easydone.egg-info/PKG-INFO +270 -0
- easydone-0.2.0/easydone.egg-info/SOURCES.txt +15 -0
- easydone-0.2.0/easydone.egg-info/dependency_links.txt +1 -0
- easydone-0.2.0/easydone.egg-info/entry_points.txt +2 -0
- easydone-0.2.0/easydone.egg-info/requires.txt +4 -0
- easydone-0.2.0/easydone.egg-info/top_level.txt +1 -0
- easydone-0.2.0/pyproject.toml +32 -0
- easydone-0.2.0/setup.cfg +4 -0
easydone-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pedro Alberto Rosquete Ares
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
easydone-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: easydone
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A CLI app made with python for easy tasks management.
|
|
5
|
+
Author-email: Pedro Alberto Rosquete Ares <rosquetearespedro06@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Pedro Alberto Rosquete Ares
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Documentation, https://github.com/prares-dev/easydone.git
|
|
29
|
+
Project-URL: Homepage, https://github.com/prares-dev/easydone.git
|
|
30
|
+
Project-URL: Repository, https://github.com/prares-dev/easydone.git
|
|
31
|
+
Requires-Python: >=3.9
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
Requires-Dist: rich>=13.0
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# easydone - Task Tracker App
|
|
40
|
+
|
|
41
|
+
> A focused command-line task manager for turning a messy to-do list into a clear next action.
|
|
42
|
+
|
|
43
|
+
easydone is a lightweight Python CLI for creating, updating, completing, deleting, and filtering tasks directly from your terminal. Tasks are saved as readable JSON, and the storage layer now includes **automatic backups, corruption quarantine, and atomic writes** to keep your data safe.
|
|
44
|
+
|
|
45
|
+
## Why easydone?
|
|
46
|
+
|
|
47
|
+
- Fast terminal-first workflow
|
|
48
|
+
- Statuses for work in motion: `not-done`, `in-progress`, and `done`
|
|
49
|
+
- Four priority levels: `low`, `normal`, `high`, and `urgent`
|
|
50
|
+
- Filter tasks by status, priority, or both
|
|
51
|
+
- Human-readable JSON storage with no database setup
|
|
52
|
+
- **Bulletproof data handling**: atomic writes, automatic `.bak` backups, and quarantine of corrupted files
|
|
53
|
+
- Pretty terminal output with [Rich](https://github.com/Textualize/rich) (falls back to plain text if unavailable)
|
|
54
|
+
|
|
55
|
+
## Project Structure
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
easydone/
|
|
59
|
+
├── easydone/
|
|
60
|
+
│ ├── __init__.py # Package metadata (version, etc.)
|
|
61
|
+
│ ├── __main__.py # Application entry point
|
|
62
|
+
│ ├── cli.py # Argument parser and command dispatch
|
|
63
|
+
│ ├── logic.py # Task-management operations
|
|
64
|
+
│ ├── storage.py # JSON loading/saving with backup & quarantine
|
|
65
|
+
│ └── format.py # Output formatting (Rich / plain)
|
|
66
|
+
├── tests/
|
|
67
|
+
│ ├── test_cli.py
|
|
68
|
+
│ ├── test_logic.py
|
|
69
|
+
│ ├── test_storage.py
|
|
70
|
+
│ └── test_format.py
|
|
71
|
+
├── LICENSE
|
|
72
|
+
├── pyproject.toml # Packaging and pytest configuration
|
|
73
|
+
└── README.md
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Quick Start
|
|
77
|
+
|
|
78
|
+
### Requirements
|
|
79
|
+
|
|
80
|
+
- Python 3.9 or newer
|
|
81
|
+
- Windows PowerShell, macOS, or Linux terminal
|
|
82
|
+
|
|
83
|
+
From the project root, create a virtual environment and install `easydone` in editable mode:
|
|
84
|
+
|
|
85
|
+
```powershell
|
|
86
|
+
py -m venv .venv
|
|
87
|
+
.\.venv\Scripts\Activate.ps1
|
|
88
|
+
py -m pip install -e .
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
On macOS or Linux:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python3 -m venv .venv
|
|
95
|
+
source .venv/bin/activate
|
|
96
|
+
python -m pip install -e .
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Or install directly from PyPI:
|
|
100
|
+
|
|
101
|
+
```powershell
|
|
102
|
+
py -m pip install easydone
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
You can now run the application:
|
|
106
|
+
|
|
107
|
+
```shell
|
|
108
|
+
easydone
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
To see all available commands:
|
|
112
|
+
|
|
113
|
+
```shell
|
|
114
|
+
easydone --help
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Everyday Workflow
|
|
118
|
+
|
|
119
|
+
Create a task:
|
|
120
|
+
|
|
121
|
+
```shell
|
|
122
|
+
easydone new "Read a book"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Create a task with a status and priority:
|
|
126
|
+
|
|
127
|
+
```shell
|
|
128
|
+
easydone new "Finish project report" --status in-progress --priority high
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
List everything:
|
|
132
|
+
|
|
133
|
+
```shell
|
|
134
|
+
easydone list
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Focus on urgent unfinished work:
|
|
138
|
+
|
|
139
|
+
```shell
|
|
140
|
+
easydone list --status not-done --priority urgent
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Mark a task as complete:
|
|
144
|
+
|
|
145
|
+
```shell
|
|
146
|
+
easydone mark 123 done
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Command Reference
|
|
150
|
+
|
|
151
|
+
### `new`
|
|
152
|
+
|
|
153
|
+
Create a task. The description is required.
|
|
154
|
+
|
|
155
|
+
```shell
|
|
156
|
+
easydone new DESCRIPTION [--status STATUS] [--priority PRIORITY]
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Options:
|
|
160
|
+
|
|
161
|
+
- `-s`, `--status`: `not-done`, `done`, or `in-progress`; defaults to `not-done`
|
|
162
|
+
- `-p`, `--priority`: `low`, `normal`, `high`, or `urgent`; defaults to `low`
|
|
163
|
+
|
|
164
|
+
### `update`
|
|
165
|
+
|
|
166
|
+
Change the description and/or priority of an existing task.
|
|
167
|
+
The `--priority` option now validates against the four allowed values.
|
|
168
|
+
|
|
169
|
+
```shell
|
|
170
|
+
easydone update TASK_ID [--description NEW_DESCRIPTION] [--priority NEW_PRIORITY]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Examples:
|
|
174
|
+
|
|
175
|
+
```shell
|
|
176
|
+
easydone update 123 --description "Read a novel"
|
|
177
|
+
easydone update 123 --priority high
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `mark`
|
|
181
|
+
|
|
182
|
+
Change the status of an existing task.
|
|
183
|
+
|
|
184
|
+
```shell
|
|
185
|
+
easydone mark TASK_ID new-status
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### `delete`
|
|
189
|
+
|
|
190
|
+
Delete one or more existing tasks. easydone tasks for confirmation for each ID unless `-f` or `--forced` is used.
|
|
191
|
+
|
|
192
|
+
```shell
|
|
193
|
+
easydone delete TASK_ID [TASK_ID ...]
|
|
194
|
+
easydone delete TASK_ID [TASK_ID ...] --forced
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
If you supply multiple IDs, all of them are validated before any deletion occurs. If any ID is invalid, the entire operation is aborted and no tasks are removed.
|
|
198
|
+
|
|
199
|
+
### `list`
|
|
200
|
+
|
|
201
|
+
List all tasks or filter them by status and priority. You can omit dates with the `--no-dates` option.
|
|
202
|
+
|
|
203
|
+
```shell
|
|
204
|
+
easydone list [--status STATUS] [--priority PRIORITY] [--no-dates]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
When both filters are supplied, a task must match both of them.
|
|
208
|
+
|
|
209
|
+
## Data Storage
|
|
210
|
+
|
|
211
|
+
`easydone` stores task data in a user‑scoped application directory so it does not depend on where the command is launched from.
|
|
212
|
+
|
|
213
|
+
- **Windows**: `%APPDATA%\easydone\tasks.json`
|
|
214
|
+
- **macOS**: `~/Library/Application Support/easydone/tasks.json`
|
|
215
|
+
- **Linux**: `~/.local/share/easydone/tasks.json`
|
|
216
|
+
|
|
217
|
+
The app writes a small metadata wrapper with the file schema version and the version of easydone that saved it. This makes future upgrades safer and compatibility warnings explicit.
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"schema_version": 1,
|
|
222
|
+
"app_version": "0.2.0",
|
|
223
|
+
"saved_at": "2026-08-28",
|
|
224
|
+
"tasks": {
|
|
225
|
+
"123": {
|
|
226
|
+
"description": "Finish project report",
|
|
227
|
+
"status": "in-progress",
|
|
228
|
+
"priority": "high",
|
|
229
|
+
"created-at": "2026-08-28",
|
|
230
|
+
"updated-at": null
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Safety & Recovery
|
|
237
|
+
|
|
238
|
+
`easydone` now protects your data in three ways:
|
|
239
|
+
|
|
240
|
+
1. **Atomic writes**: Every save writes to a temporary file first, then swaps it atomically. A crash mid‑write never leaves a half‑written file.
|
|
241
|
+
2. **Automatic backups**: Before every save, the current `tasks.json` is copied to `tasks.json.bak`. If something goes wrong, you can restore from this backup.
|
|
242
|
+
3. **Corruption quarantine**: If easydone encounters an unreadable or malformed file on load, it copies that file to `tasks.corrupted-<timestamp>.json` instead of discarding it. You can inspect the quarantined file and recover data manually.
|
|
243
|
+
|
|
244
|
+
If an older file is found (different schema or app version), `easydone` still loads it but prints a detailed warning so you can review the data before saving again.
|
|
245
|
+
|
|
246
|
+
## Development
|
|
247
|
+
|
|
248
|
+
Install the development dependency group:
|
|
249
|
+
|
|
250
|
+
```shell
|
|
251
|
+
py -m pip install -e ".[dev]"
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Run the complete test suite:
|
|
255
|
+
|
|
256
|
+
```shell
|
|
257
|
+
py -m pytest
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Run a specific test module:
|
|
261
|
+
|
|
262
|
+
```shell
|
|
263
|
+
py -m pytest tests/logic_test.py
|
|
264
|
+
py -m pytest tests/storage_test.py
|
|
265
|
+
py -m pytest tests/format_test.py
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
This project is available under the license in [LICENSE](LICENSE).
|
easydone-0.2.0/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# easydone - Task Tracker App
|
|
2
|
+
|
|
3
|
+
> A focused command-line task manager for turning a messy to-do list into a clear next action.
|
|
4
|
+
|
|
5
|
+
easydone is a lightweight Python CLI for creating, updating, completing, deleting, and filtering tasks directly from your terminal. Tasks are saved as readable JSON, and the storage layer now includes **automatic backups, corruption quarantine, and atomic writes** to keep your data safe.
|
|
6
|
+
|
|
7
|
+
## Why easydone?
|
|
8
|
+
|
|
9
|
+
- Fast terminal-first workflow
|
|
10
|
+
- Statuses for work in motion: `not-done`, `in-progress`, and `done`
|
|
11
|
+
- Four priority levels: `low`, `normal`, `high`, and `urgent`
|
|
12
|
+
- Filter tasks by status, priority, or both
|
|
13
|
+
- Human-readable JSON storage with no database setup
|
|
14
|
+
- **Bulletproof data handling**: atomic writes, automatic `.bak` backups, and quarantine of corrupted files
|
|
15
|
+
- Pretty terminal output with [Rich](https://github.com/Textualize/rich) (falls back to plain text if unavailable)
|
|
16
|
+
|
|
17
|
+
## Project Structure
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
easydone/
|
|
21
|
+
├── easydone/
|
|
22
|
+
│ ├── __init__.py # Package metadata (version, etc.)
|
|
23
|
+
│ ├── __main__.py # Application entry point
|
|
24
|
+
│ ├── cli.py # Argument parser and command dispatch
|
|
25
|
+
│ ├── logic.py # Task-management operations
|
|
26
|
+
│ ├── storage.py # JSON loading/saving with backup & quarantine
|
|
27
|
+
│ └── format.py # Output formatting (Rich / plain)
|
|
28
|
+
├── tests/
|
|
29
|
+
│ ├── test_cli.py
|
|
30
|
+
│ ├── test_logic.py
|
|
31
|
+
│ ├── test_storage.py
|
|
32
|
+
│ └── test_format.py
|
|
33
|
+
├── LICENSE
|
|
34
|
+
├── pyproject.toml # Packaging and pytest configuration
|
|
35
|
+
└── README.md
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
### Requirements
|
|
41
|
+
|
|
42
|
+
- Python 3.9 or newer
|
|
43
|
+
- Windows PowerShell, macOS, or Linux terminal
|
|
44
|
+
|
|
45
|
+
From the project root, create a virtual environment and install `easydone` in editable mode:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
py -m venv .venv
|
|
49
|
+
.\.venv\Scripts\Activate.ps1
|
|
50
|
+
py -m pip install -e .
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
On macOS or Linux:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python3 -m venv .venv
|
|
57
|
+
source .venv/bin/activate
|
|
58
|
+
python -m pip install -e .
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or install directly from PyPI:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
py -m pip install easydone
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You can now run the application:
|
|
68
|
+
|
|
69
|
+
```shell
|
|
70
|
+
easydone
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
To see all available commands:
|
|
74
|
+
|
|
75
|
+
```shell
|
|
76
|
+
easydone --help
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Everyday Workflow
|
|
80
|
+
|
|
81
|
+
Create a task:
|
|
82
|
+
|
|
83
|
+
```shell
|
|
84
|
+
easydone new "Read a book"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Create a task with a status and priority:
|
|
88
|
+
|
|
89
|
+
```shell
|
|
90
|
+
easydone new "Finish project report" --status in-progress --priority high
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
List everything:
|
|
94
|
+
|
|
95
|
+
```shell
|
|
96
|
+
easydone list
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Focus on urgent unfinished work:
|
|
100
|
+
|
|
101
|
+
```shell
|
|
102
|
+
easydone list --status not-done --priority urgent
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Mark a task as complete:
|
|
106
|
+
|
|
107
|
+
```shell
|
|
108
|
+
easydone mark 123 done
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Command Reference
|
|
112
|
+
|
|
113
|
+
### `new`
|
|
114
|
+
|
|
115
|
+
Create a task. The description is required.
|
|
116
|
+
|
|
117
|
+
```shell
|
|
118
|
+
easydone new DESCRIPTION [--status STATUS] [--priority PRIORITY]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Options:
|
|
122
|
+
|
|
123
|
+
- `-s`, `--status`: `not-done`, `done`, or `in-progress`; defaults to `not-done`
|
|
124
|
+
- `-p`, `--priority`: `low`, `normal`, `high`, or `urgent`; defaults to `low`
|
|
125
|
+
|
|
126
|
+
### `update`
|
|
127
|
+
|
|
128
|
+
Change the description and/or priority of an existing task.
|
|
129
|
+
The `--priority` option now validates against the four allowed values.
|
|
130
|
+
|
|
131
|
+
```shell
|
|
132
|
+
easydone update TASK_ID [--description NEW_DESCRIPTION] [--priority NEW_PRIORITY]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Examples:
|
|
136
|
+
|
|
137
|
+
```shell
|
|
138
|
+
easydone update 123 --description "Read a novel"
|
|
139
|
+
easydone update 123 --priority high
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `mark`
|
|
143
|
+
|
|
144
|
+
Change the status of an existing task.
|
|
145
|
+
|
|
146
|
+
```shell
|
|
147
|
+
easydone mark TASK_ID new-status
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `delete`
|
|
151
|
+
|
|
152
|
+
Delete one or more existing tasks. easydone tasks for confirmation for each ID unless `-f` or `--forced` is used.
|
|
153
|
+
|
|
154
|
+
```shell
|
|
155
|
+
easydone delete TASK_ID [TASK_ID ...]
|
|
156
|
+
easydone delete TASK_ID [TASK_ID ...] --forced
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
If you supply multiple IDs, all of them are validated before any deletion occurs. If any ID is invalid, the entire operation is aborted and no tasks are removed.
|
|
160
|
+
|
|
161
|
+
### `list`
|
|
162
|
+
|
|
163
|
+
List all tasks or filter them by status and priority. You can omit dates with the `--no-dates` option.
|
|
164
|
+
|
|
165
|
+
```shell
|
|
166
|
+
easydone list [--status STATUS] [--priority PRIORITY] [--no-dates]
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
When both filters are supplied, a task must match both of them.
|
|
170
|
+
|
|
171
|
+
## Data Storage
|
|
172
|
+
|
|
173
|
+
`easydone` stores task data in a user‑scoped application directory so it does not depend on where the command is launched from.
|
|
174
|
+
|
|
175
|
+
- **Windows**: `%APPDATA%\easydone\tasks.json`
|
|
176
|
+
- **macOS**: `~/Library/Application Support/easydone/tasks.json`
|
|
177
|
+
- **Linux**: `~/.local/share/easydone/tasks.json`
|
|
178
|
+
|
|
179
|
+
The app writes a small metadata wrapper with the file schema version and the version of easydone that saved it. This makes future upgrades safer and compatibility warnings explicit.
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"schema_version": 1,
|
|
184
|
+
"app_version": "0.2.0",
|
|
185
|
+
"saved_at": "2026-08-28",
|
|
186
|
+
"tasks": {
|
|
187
|
+
"123": {
|
|
188
|
+
"description": "Finish project report",
|
|
189
|
+
"status": "in-progress",
|
|
190
|
+
"priority": "high",
|
|
191
|
+
"created-at": "2026-08-28",
|
|
192
|
+
"updated-at": null
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Safety & Recovery
|
|
199
|
+
|
|
200
|
+
`easydone` now protects your data in three ways:
|
|
201
|
+
|
|
202
|
+
1. **Atomic writes**: Every save writes to a temporary file first, then swaps it atomically. A crash mid‑write never leaves a half‑written file.
|
|
203
|
+
2. **Automatic backups**: Before every save, the current `tasks.json` is copied to `tasks.json.bak`. If something goes wrong, you can restore from this backup.
|
|
204
|
+
3. **Corruption quarantine**: If easydone encounters an unreadable or malformed file on load, it copies that file to `tasks.corrupted-<timestamp>.json` instead of discarding it. You can inspect the quarantined file and recover data manually.
|
|
205
|
+
|
|
206
|
+
If an older file is found (different schema or app version), `easydone` still loads it but prints a detailed warning so you can review the data before saving again.
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
Install the development dependency group:
|
|
211
|
+
|
|
212
|
+
```shell
|
|
213
|
+
py -m pip install -e ".[dev]"
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Run the complete test suite:
|
|
217
|
+
|
|
218
|
+
```shell
|
|
219
|
+
py -m pytest
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Run a specific test module:
|
|
223
|
+
|
|
224
|
+
```shell
|
|
225
|
+
py -m pytest tests/logic_test.py
|
|
226
|
+
py -m pytest tests/storage_test.py
|
|
227
|
+
py -m pytest tests/format_test.py
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
This project is available under the license in [LICENSE](LICENSE).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
# use the distribution name from pyproject 'project.name' (make sure they match)
|
|
5
|
+
__version__ = version("easydone-task-tracker")
|
|
6
|
+
except PackageNotFoundError:
|
|
7
|
+
# Package isn't installed (dev environment). Optional fallback:
|
|
8
|
+
__version__ = "0.0.0+dev"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .cli import Parser
|
|
2
|
+
from .logic import TasksManager
|
|
3
|
+
from .storage import JSONHandler
|
|
4
|
+
from .format import describe_load_result, report_backup
|
|
5
|
+
|
|
6
|
+
def main() -> None:
|
|
7
|
+
# JSONHandler instance for load/save in .json.
|
|
8
|
+
handler = JSONHandler()
|
|
9
|
+
load_result = handler.load()
|
|
10
|
+
describe_load_result(load_result)
|
|
11
|
+
|
|
12
|
+
# TasksManager instance based on tasks loaded
|
|
13
|
+
manager = TasksManager(tasks_from_file=load_result.tasks)
|
|
14
|
+
|
|
15
|
+
# Parser instance for cli interface and argumments
|
|
16
|
+
cli = Parser(manager)
|
|
17
|
+
mutated = cli.start_parsing()
|
|
18
|
+
|
|
19
|
+
# save tasks before exiting only if mutated status
|
|
20
|
+
if mutated:
|
|
21
|
+
backup_result = handler.save(manager.tasks)
|
|
22
|
+
report_backup(backup_result)
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|