timewarrior
timewarrior copied to clipboard
on-modify.timewarrior: The start command does not accept ranges but only a single datetime.
It seems like the hook script doesn't like it, when a given tag can be read as time/date:
The script works fine without a tag:
tasksh> add 'Test Timewarrior'
[task add 'Test Timewarrior']
Created task 302.
tasksh> start 302
[task start 302]
Starting task a36684d6 'Test Timewarrior'.
Started 1 task.
Tracking "Test Timewarrior"
Started 2021-09-24T08:12:10
Current 10
Total 0:00:00
You have more urgent tasks.
tasksh> stop 302
[task stop 302]
Stopping task a36684d6 'Test Timewarrior'.
Stopped 1 task.
Recorded "Test Timewarrior"
Started 2021-09-24T08:12:10
Ended 12
Total 0:00:02
Script fails with the tag today
:
tasksh> 302 mod +today
[task 302 mod +today]
Modifying task 302 'Test Timewarrior'.
Modified 1 task.
tasksh> start 302
[task start 302]
The start command does not accept ranges but only a single datetime. Perhaps you want the track command?
Starting task a36684d6 'Test Timewarrior'.
Started 1 task.
tasksh> stop 302
[task stop 302]
There is no active time tracking.
Stopping task a36684d6 'Test Timewarrior'.
Stopped 1 task.
Tag anything
works fine again:
tasksh> 302 mod -today +anything
[task 302 mod -today +anything]
Modifying task 302 'Test Timewarrior'.
Modified 1 task.
tasksh> start 302
[task start 302]
Starting task a36684d6 'Test Timewarrior'.
Started 1 task.
Note: 'anything' is a new tag.
Tracking "Test Timewarrior" anything
Started 2021-09-24T08:14:21
Current 21
Total 0:00:00
You have more urgent tasks.
tasksh> stop 302
[task stop 302]
Stopping task a36684d6 'Test Timewarrior'.
Stopped 1 task.
Recorded "Test Timewarrior" anything
Started 2021-09-24T08:14:21
Ended 23
Total 0:00:02
Anything I can do to fix of help to solve the problem?
Thanks for your work!
It just found and tried the debug hook script:
Installed the file as on-modify-debug.timewarrior
in ~/.task/hooks
and made it executable with chmod +x on-modify-debug.timewarrior
but receive the following error:
tasksh> start 302
[task start 302]
Hook Error: Expected 1 JSON task(s), found 2, in hook script: on-modify-debug.timewarrior
What did I do wrong? Anything I can provide to help to solve the problem? Thanks!
Not sure what is going on, but the hooks docs states for the input:
Input to hook scripts consists of JSON-formatted objects, one per line [...] the task must occupy only one line of output.
and for the output:
The output is a single line JSON object which represents an optionally modified task, and a single line of feedback text to be displayed. There may only be one line of JSON, and it must be for the same task that was provided as input.
But this does not seem be true in my setup:
❯ task 302 export
[
{"id":302,"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519","urgency":0}
]
❯ task 302 export | wc -l
3
❯ task 302 export | ./on-modify-debug.timewarrior
[
{"id":302,"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519","urgency":0}
]
❯ task 302 export | ./on-modify-debug.timewarrior | wc -l
3
Im on Debian/bullseye with the following versions of timewarrior/taskwarrior:
❯ dpkg -l taskwarrior timewarrior | tail -2
ii taskwarrior 2.5.3+dfsg-4 amd64 feature-rich console based todo list manager
ii timewarrior 1.4.2+ds.1-3 amd64 feature-rich time tracking utility
❯ task config debug 1
❯ task config debug.hooks 2
❯ task start 302
Timer Config::load (/home/jkirk/.taskrc) 0.000341 sec
No context.
Found misnamed hook script /home/jkirk/.task/hooks/disable.on-modify.timewarrior
Found hook script /home/jkirk/.task/hooks/on-modify-debug.timewarrior
Parse Tree (before command-specifіc processing)
_original_args
task start 302
_args
word basename='task' raw='task' BINARY
dom canonical='start' raw='start' ORIGINAL CMD USESCONTEXT ALLOWSFILTER ALLOWSMODIFICATIONS
number raw='302' ORIGINAL MODIFICATION
Filtered 302 tasks --> 1 tasks [pending only]
Hook: Calling /home/jkirk/.task/hooks/on-modify-debug.timewarrior
Hook: input
{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}
{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","start":"20210924T090024Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}
Hooks: args
api:2
args:task start 302
command:start
rc:/home/jkirk/.taskrc
data:/home/jkirk/.task
version:2.5.3
Timer Hooks::execute (/home/jkirk/.task/hooks/on-modify-debug.timewarrior) 0.023575 sec
Hook: output
{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}
{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","start":"20210924T090024Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}
Hook: Completed with status 0
Hook Error: Expected 1 JSON task(s), found 2, in hook script: on-modify-debug.timewarrior
So the debug hook script doesn't seem to return what is expected:
❯ (echo "{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}"; echo "{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","start":"20210924T090829Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}") | ./on-modify-debug.timewarrior
{description:Test Timewarrior,entry:20210924T061208Z,modified:20210924T063353Z,status:pending,uuid:a36684d6-253e-4bae-9cc6-4496de260519}
{description:Test Timewarrior,entry:20210924T061208Z,modified:20210924T063353Z,start:20210924T090829Z,status:pending,uuid:a36684d6-253e-4bae-9cc6-4496de260519}
But ok, this seems to be another problem. Finally I ended up here...
❯ (echo "{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}"; echo "{"description":"Test Timewarrior","entry":"20210924T061208Z","modified":"20210924T063353Z","start":"20210924T090829Z","status":"pending","uuid":"a36684d6-253e-4bae-9cc6-4496de260519"}") | ./disable.on-modify.timewarrior
Traceback (most recent call last):
File "/home/jkirk/Documents/taskwarrior/.task/hooks/./disable.on-modify.timewarrior", line 48, in <module>
old = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.9/json/decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Silly me, the quotes were wrong:
❯ (echo '{"description":"Test Timewarrior","entry":"20210924T061036Z","modified":"20210924T061054Z","status":"pending","tags":["today"],"uuid":"e605becc-0e83-4e32-92f7-c61ff688e7ed"}'; echo '{"description":"Test Timewarrior","entry":"20210924T061036Z","modified":"20210924T061054Z","start":"20210924T100015Z","status":"pending","tags":["today"],"uuid":"e605becc-0e83-4e32-92f7-c61ff688e7ed"}') | ./disable.on-modify.timewarrior
{"description": "Test Timewarrior", "entry": "20210924T061036Z", "modified": "20210924T061054Z", "start": "20210924T100015Z", "status": "pending", "tags": ["today"], "uuid": "e605becc-0e83-4e32-92f7-c61ff688e7ed"}
The start command does not accept ranges but only a single datetime. Perhaps you want the track command?
Which finally leads to this:
❯ timew start Test Timewarrior today :yes
The start command does not accept ranges but only a single datetime. Perhaps you want the track command?
Sorry for my debug noise above, but it was quite hard for me (as this was my first time debugging taskwarrior/timewarrior).
Hi @jkirk! Thanks for your detailled analysis. I am currently still looking at it and analyzing the issue myself.
Ran into a similar (same?) issue, took me a while after reading this thread to realise that the tag "sep" I was using is considered time-related if interpreted as shorthand for "September" (which I didn't even mean, it was an acronym). I'm on Arch with TaskWarrior version 2.5.3 and TimeWarrior 1.4.3.
I'm having the same problem with a tag friday
I was using. Changing to other tag name fixed the problem. Thanks.
@jkirk it is not a problem of the on-modify.timewarrior
hook.
It is a general problem of Timewarrior that it does not accept tags which resemble date values. The reasons is the command line parser which is a bit to eager to interpret them as date values/ranges even if there is none required. It will require a bit more restructuring to solve this... 🤔
(see #60 #154 #383)
I've found a workaround that works for me. I use GTD methodology with taskwarrior (I believe I came to something that works wonderfully by the way) and so I have some context tags as the time I think the task will take, so depending on the time context I can filter tasks that will take 5, 15, 30 45 or 60 minutes, then 1, 2 or 4 hours.
What "fixed" it for me was replacing, for example, the tag +15min with the tag +_15min. Having an underscore in front of it made all the difference.
I hope this is useful for most of you guys (and you can check the attachment too where I show a task was correctly logged in TimeWarrior; I've obfuscated some confidential company stuff that can identify where it is, but you can see it fine).
timewarrior should just interpret everything after it sees 'start' as a tag, without further interpretation. I am having a similar issue in #455, perhaps this is same root issue that parser keeps looking for more after it shouldn't
A better solution is to make tags special, may be tags must be prefixed with +
like in taskwarrior so the command be:
timew start [<date>] [<+tag> ...]
note that I use tags that start with a +
to mean "tags that came from taskwarrior" and not all of them do. we could say exactly one +
will be stripped, and the rest is a tag. So ++foo
would give me a tag of +foo
.
Each ++
should be replaced with +
thus allowing ++++tag
to be parsed as ++tag
and
+today
to be enforced as a tag today
prevPlus = false
newArg = ""
for (char : arg) {
if (char == '+') {
if (prevPlus) {
newTag += '+'
prevPlus = false
} else {
prevPlus = true
}
} else {
newTag += char
}
}
return arg[0] == '+' ? parseAsTag(newArg) : parseNotTag(newArg)
Ran into this today using taskwarrior tag weekly
, changing it to _weekly
worked around the issue. Thanks for the debugging @jkirk and suggestion @tiagommmelo