whatnext 3.3__tar.gz → 3.3.2__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.
- {whatnext-3.3 → whatnext-3.3.2}/CHANGELOG.md +10 -0
- {whatnext-3.3 → whatnext-3.3.2}/PKG-INFO +1 -1
- {whatnext-3.3 → whatnext-3.3.2}/docs/deferring.md +1 -1
- whatnext-3.3.2/tests/deferring/dir-complete/tasks.md +3 -0
- whatnext-3.3.2/tests/deferring/needs-dir-complete.md +3 -0
- whatnext-3.3.2/tests/deferring/needs-subdir.md +3 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring.bats +23 -2
- {whatnext-3.3 → whatnext-3.3.2}/tests/headerless/annotation.md +1 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/list.bats +1 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_file.py +55 -0
- {whatnext-3.3 → whatnext-3.3.2}/whatnext/models.py +3 -1
- {whatnext-3.3 → whatnext-3.3.2}/whatnext/whatnext.py +9 -1
- {whatnext-3.3 → whatnext-3.3.2}/.flake8 +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/.github/dependabot.yml +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/.github/workflows/publish.yml +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/.github/workflows/tests.yml +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/.gitignore +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/.whatnext +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/LICENCE +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/LICENSE +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/Makefile +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/README.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/archive/done/tasks.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/annotations.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/basics.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/deadlines.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/exclusions.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/index.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/installation.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/next.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/prioritisation.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/sequential.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/docs/usage.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/archived/projects/tangerine.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/projects/curtain.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/projects/fountain.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/projects/harvest.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/projects/obelisk.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/projects/tinsel.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/tasks.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/example/template.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/pyproject.toml +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/scripts/update-usage-examples.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/deferring.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/documentation.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/ignoring.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/listing.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/next.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/summaries.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/test_refactor.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_0.1.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_0.2.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_0.3.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_0.4.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_0.5.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_1.0.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_1.1.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_1.2.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks/version_1.3.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tasks.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/colour.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/config/.whatnext +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/config/.whatnext.alt +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/config/apples.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/config/oranges.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/config-external +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/config.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deadline.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/bare-after.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/circular-a.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/circular-b.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/deferred.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/duplicate-warnings.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/missing-dep.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/needs-absolute.md +0 -0
- /whatnext-3.3/tests/deferring/needs-subdir.md → /whatnext-3.3.2/tests/deferring/needs-subdir-file.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/phase-misplaced.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/phases-empty.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/phases-partial.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/phases-queue.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/phases.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/regular.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/root-target.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/samename.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/subdir/needs-parent.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/subdir/needs-sibling.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/subdir/samename.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/deferring/subdir/target.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/edit.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/headerless/deadline.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/housekeeping.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/invalid.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/matching.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/alternate.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/append-after.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/append.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/empty.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/insert.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/projects/alpha/tasks/things.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/projects/alpha/tasks.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/projects/beta/things.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/something.txt +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/tasks.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/wide.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next/wrapped.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/next.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/notnext.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/queue/all-complete.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/queue/blocked.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/queue/in-progress.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/queue/normal.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/queue/prioritised.md +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/queue.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/summary.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_defer.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_edit.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_limit.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_output.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_summary.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/test_task.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/usage.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/tests/version.bats +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/whatnext/__init__.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/whatnext/guide.txt +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/whatnext/next.py +0 -0
- {whatnext-3.3 → whatnext-3.3.2}/whatnext/summary.py +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [v3.3.2] - 2026-04-17
|
|
5
|
+
|
|
6
|
+
**Fixes:** `@after` with a directory waits on all tasks under that dir.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## [v3.3.1] - 2026-04-17
|
|
10
|
+
|
|
11
|
+
**Fixes:** Empty tasks (`- [ ]\n`) no longer cause a stacktrace.
|
|
12
|
+
|
|
13
|
+
|
|
4
14
|
## [v3.3] - 2026-04-13
|
|
5
15
|
|
|
6
16
|
**Added:**
|
|
@@ -37,7 +37,7 @@ Filenames are resolved relative to the file containing the `@after`
|
|
|
37
37
|
directive.
|
|
38
38
|
|
|
39
39
|
@after ../project-b/setup.md
|
|
40
|
-
@after subtask/
|
|
40
|
+
@after subtask/
|
|
41
41
|
@after ~/tasks/dependency.md
|
|
42
42
|
|
|
43
43
|
Circular dependencies (where A depends on B and B depends on A) will
|
|
@@ -154,14 +154,14 @@ teardown_file() {
|
|
|
154
154
|
|
|
155
155
|
@test "after resolves path descending into subdirectory" {
|
|
156
156
|
expected_output=$(sed -e 's/^ //' <<" EOF"
|
|
157
|
-
tests/deferring/needs-subdir.md:
|
|
157
|
+
tests/deferring/needs-subdir-file.md:
|
|
158
158
|
- [ ] depends on subdir file
|
|
159
159
|
EOF
|
|
160
160
|
)
|
|
161
161
|
|
|
162
162
|
run --separate-stderr \
|
|
163
163
|
whatnext \
|
|
164
|
-
tests/deferring/needs-subdir.md \
|
|
164
|
+
tests/deferring/needs-subdir-file.md \
|
|
165
165
|
tests/deferring/subdir/target.md
|
|
166
166
|
|
|
167
167
|
diff -u <(echo "$expected_output") <(echo "$output")
|
|
@@ -392,3 +392,24 @@ teardown_file() {
|
|
|
392
392
|
diff -u <(echo "$expected_output") <(echo "$output")
|
|
393
393
|
[ $status -eq 0 ]
|
|
394
394
|
}
|
|
395
|
+
|
|
396
|
+
@test "after directory with incomplete tasks hides deferred task" {
|
|
397
|
+
run whatnext tests/deferring/needs-subdir.md
|
|
398
|
+
|
|
399
|
+
diff -u <(echo "") <(echo "$output")
|
|
400
|
+
[ $status -eq 0 ]
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
@test "after directory with all complete tasks shows deferred task" {
|
|
404
|
+
expected_output=$(sed -e 's/^ //' <<" EOF"
|
|
405
|
+
tests/deferring/needs-dir-complete.md:
|
|
406
|
+
# Waiting
|
|
407
|
+
- [ ] depends on directory
|
|
408
|
+
EOF
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
run whatnext tests/deferring/needs-dir-complete.md
|
|
412
|
+
|
|
413
|
+
diff -u <(echo "$expected_output") <(echo "$output")
|
|
414
|
+
[ $status -eq 0 ]
|
|
415
|
+
}
|
|
@@ -122,6 +122,61 @@ class TestFileParsing:
|
|
|
122
122
|
"phase": None,
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
def test_empty_task(self):
|
|
126
|
+
file = MarkdownFile(
|
|
127
|
+
source_string="- [ ]",
|
|
128
|
+
today=date(2025, 1, 1),
|
|
129
|
+
)
|
|
130
|
+
assert len(file.tasks) == 1
|
|
131
|
+
assert file.tasks[0].as_dict() == {
|
|
132
|
+
"heading": None,
|
|
133
|
+
"state": State.OPEN,
|
|
134
|
+
"text": "",
|
|
135
|
+
"priority": Priority.NORMAL,
|
|
136
|
+
"due": None,
|
|
137
|
+
"imminent": None,
|
|
138
|
+
"annotation": None,
|
|
139
|
+
"line": 1,
|
|
140
|
+
"deferred": None,
|
|
141
|
+
"phase": None,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
def test_empty_task_with_deadline(self):
|
|
145
|
+
# regex looks for text before @, so this becomes literal text
|
|
146
|
+
file = MarkdownFile(
|
|
147
|
+
source_string="- [ ] @2025-06-15",
|
|
148
|
+
today=date(2025, 1, 1),
|
|
149
|
+
)
|
|
150
|
+
assert len(file.tasks) == 1
|
|
151
|
+
assert file.tasks[0].text == "@2025-06-15"
|
|
152
|
+
assert file.tasks[0].due is None
|
|
153
|
+
|
|
154
|
+
def test_empty_task_with_after(self):
|
|
155
|
+
# regex looks for text before @, so this becomes literal text
|
|
156
|
+
file = MarkdownFile(
|
|
157
|
+
source_string="- [ ] @after other.md",
|
|
158
|
+
today=date(2025, 1, 1),
|
|
159
|
+
)
|
|
160
|
+
assert len(file.tasks) == 1
|
|
161
|
+
assert file.tasks[0].text == "@after other.md"
|
|
162
|
+
assert file.tasks[0].deferred is None
|
|
163
|
+
|
|
164
|
+
def test_text_without_space_after_marker(self):
|
|
165
|
+
file = MarkdownFile(
|
|
166
|
+
source_string="- [ ]text on the marker",
|
|
167
|
+
today=date(2025, 1, 1),
|
|
168
|
+
)
|
|
169
|
+
assert len(file.tasks) == 1
|
|
170
|
+
assert file.tasks[0].text == "text on the marker"
|
|
171
|
+
|
|
172
|
+
def test_multiple_spaces_after_marker(self):
|
|
173
|
+
file = MarkdownFile(
|
|
174
|
+
source_string="- [ ] text away from the marker",
|
|
175
|
+
today=date(2025, 1, 1),
|
|
176
|
+
)
|
|
177
|
+
assert len(file.tasks) == 1
|
|
178
|
+
assert file.tasks[0].text == "text away from the marker"
|
|
179
|
+
|
|
125
180
|
def test_in_progress_task(self):
|
|
126
181
|
file = MarkdownFile(
|
|
127
182
|
source_string="- [/] in progress, this task is partially complete",
|
|
@@ -290,6 +290,8 @@ class MarkdownFile:
|
|
|
290
290
|
@staticmethod
|
|
291
291
|
def parse_deadline(text):
|
|
292
292
|
match = MarkdownFile.DEADLINE_PATTERN.match(text)
|
|
293
|
+
if match is None:
|
|
294
|
+
return (None, None, text)
|
|
293
295
|
cleaned = match.group(1)
|
|
294
296
|
date_str = match.group(2)
|
|
295
297
|
if date_str is None:
|
|
@@ -638,7 +640,7 @@ class MarkdownFile:
|
|
|
638
640
|
self.max_task_line_width, len(continuation_line)
|
|
639
641
|
)
|
|
640
642
|
text += " " + continuation_line.strip()
|
|
641
|
-
task_content = text[prefix_width:]
|
|
643
|
+
task_content = text[prefix_width - 1:].lstrip()
|
|
642
644
|
task = self.parse_task(
|
|
643
645
|
heading,
|
|
644
646
|
heading_priority,
|
|
@@ -125,9 +125,17 @@ def filter_deferred(data, ignore_patterns):
|
|
|
125
125
|
basename = os.path.basename(path)
|
|
126
126
|
if is_dependency_ignored(basename, ignore_patterns):
|
|
127
127
|
return True
|
|
128
|
+
if os.path.isdir(path):
|
|
129
|
+
for root, dirs, files in os.walk(path):
|
|
130
|
+
for filename in files:
|
|
131
|
+
if filename.endswith(".md"):
|
|
132
|
+
filepath = os.path.join(root, filename)
|
|
133
|
+
if not is_file_complete(filepath):
|
|
134
|
+
return False
|
|
135
|
+
return True
|
|
128
136
|
if path in file_by_path:
|
|
129
137
|
file = file_by_path[path]
|
|
130
|
-
elif os.path.
|
|
138
|
+
elif os.path.isfile(path):
|
|
131
139
|
file = MarkdownFile(source=path, today=all_files[0].today)
|
|
132
140
|
else:
|
|
133
141
|
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/whatnext-3.3/tests/deferring/needs-subdir.md → /whatnext-3.3.2/tests/deferring/needs-subdir-file.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|