For one, it is not necessary: the first argument on the command line is not used any
further when executing the command line. Also, if there is an extension that starts
with the same string as the binary, the binary gets also marked as an extension.
This in turn prohibits the detection of any other Timewarrior command such that e.g.
the command 'summary' in 'timew summary' is treated as an external report, which is
not present and thus makes the call fail.
Closes#677
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Additionally, this also makes the syntax of the `modify` command more flexible.
Before, the sub-command had to follow right after the `modify` command, now one can also write it with the id between command and sub-command:
```
$ timew modify @1 start 09:30
```
The `range` sub-command modifies both start and end time of the interval. It expects a range as parameter, e.g.
```
$ timew modify @3 range 08:15 - 13:37
```
Closes#627
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Install man pages from tar ball
The generated man pages are already present in the tar ball.
Simply install those then, even if Asciidoctor is not present.
Optimize CMake files.
Closes#620
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Remove 'version' from docker-compose.yml
- Add Asciidoctor version to informative output
- Fix Asciidoctor install on OpenSUSE Tumbleweed
- Add Ubuntu 24.04 to test zoo
- Drop Ubuntu 18.04 from test zoo
- Add Fedora 40 to test zoo
- Add Fedora 41 to test zoo
- Drop Fedora 37 from test zoo
- Drop Fedora 38 from test zoo
Closes#648
- Add defines for the values that are allowed for epoch timestamps
- Fix wrong week number output when weekstart=0
- Add bold color with 256 color space
Python upstream is trying to eliminate tz-naive date functions that
imply anything to do with a timezone, even UTC. They have deprecated
datetime.datetime.utcnow() in Python 3.12 and thus running tests emits
many warnings for us.
We switch to instantiate datetime objects taht are intended to reflect
UTC to have a timezone, or if we instantiate naive ones and then later
convert, we do the full conversion.
After the changes, the tests still work on Python 3.9, but now also on
Python 3.12 without warnings.
See PR description for #632 for more details.
Signed-off-by: Scott Mcdermott <scott@smemsh.net>
This is a duplicate of the changes from commit with same subject line in
GothenburgBitFactory/libshared#81 and also duplicates the commit
message below. Timewarrior has copies of many functions from
libshared's Datetime class in its own DatetimeParser class, and until
such time as these classes are integrated, we have to maintain copies of
these functions here, and the changes need to be duplicated. See
discussion in aforementioned PR.
The one difference with the patch over there is, this one is using the
public Datetime::dayOfWeek() and Datetime::daysInYear() methods from
libshared, rather than its own implementation. The copy in Timewarrior
already was doing this before, but it's worth noting it's the only
difference with the corresponding patch in libshared PR 81, and only
amounts to a change in the namespace qualifier.
Copied commit message from libshared follows.
* * *
This patch makes the parsing of week numbers in dates ISO-8601 compliant
in the case that Datetime::weekstart == 1, while the existing behavior
remains available if Datetime::weekstart == 0.
The previous code parsed week numbers (given as "yyyy-Www") into dates
starting on Sunday. Although the code had a "Datetime::weekstart"
variable, and this value was initialized to 1 (which is Monday) in
libshared, nonetheless week specifications would be parsed into calendar
days starting on Sunday.
Furthermore, week days in such given weeks ('d' in "yyyy-Www-d") used 0-6
for Sunday-Monday, while ISO8601 specifies 1-7 Monday-Sunday.
Therefore, yyyy-Www-0 was treated as valid (and should not be), while
yyyy-Www-7 was invalid (and should be valid).
Note that neither Taskwarrior nor Timewarrior ever set the value of
Datetime::weekstart. Taskwarrior has an rc.weekstart, but this is only
used for "task calendar" output, not for parsing dates.
The patch does the following:
- Initialize "Datetime" instances with a weekday value from
Datetime::weekstart. This helps the case when weekday is not
supplied, it won't default to zero and fail validation (when
weekstart is '1'). Note that mktime() is usually used in the code
to convert populated "struct tm" broken-down times into epoch-times,
and this operation does not use tm.tm_wday for input, only as an
output field, recomputed as a normalized value, so it appears to be
safe to initialize it with a 1 (which we might wonder about since
.tm_wday is supposed to be 0-6 Sunday based).
- Use the already-existing Datetime::parse_weekday() to parse the
'ww' in "yyyy-Www" input dates (the function was not used by any
caller previously; guessing it may have been intended for eventual
use in order to respect weekstart(?))
- Teach parse_weekday() about weekstart. Previously this assumed
1-7, which is the reason I'm guessing this was intended to be used
for ISO weeks eventually. Now it can also use 0-6 if weekstart 0.
- Teach Datetime::validate to respect Datetime::weekstart also.
Previously only 0-6 Sunday-Monday was considered valid.
- Default the weekday to Datetime::weekstart if not supplied, ie for
"yyyy-Www-X" if the "-X" is not supplied, as recognized when
Datetime::standaloneDateEnabled = true, which is the case for (1)
tests, (2) timewarrior, but NOT for taskwarrior at this time
(both the standalone 'calc' and 'task calc' (ie Context.cpp) set
this to false).
- Implement the complete ISO week calculation algorithm in
Datetime::resolve() if weekstart is '1', and keeps the existing
algorithm if weekstart is '0'. This will allow Taskwarrior and
Timewarrior to offer the option of the old behavior for those
who want to use Sunday-based weeks and ignore ISO week calculations
(such as 2023-01-01 being in ISO week 2022-W52).
Signed-off-by: Scott Mcdermott <scott@smemsh.net>
This corrects for some drift in our shadowed copy of libshared's
Datetime::validate (in our own DatetimeParser class with function of
same name), from libshared commit 7dffb13c
Signed-off-by: Scott Mcdermott <scott@smemsh.net>
Apparently "docker-compose" was deprecated over 6 months ago and is
starting to be phased out in favor of "docker compose". Without this,
test runners are getting:
home/runner/work/_temp/0af6641a-337b-4651-8ca4-fef3529091af.sh: line 1:
docker-compose: command not found
See https://github.com/orgs/community/discussions/116610 for details
Signed-off-by: Scott <scott@smemsh.net>
CentOS 8 reached end of life on 2021-12-31 (CentOS Stream8 on 2024-05-31)
CentOS 7 reaches end of life on 2024-06-30
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Use UnitTest::ok in UnitTest::notok
- Extract report_* functions
- Extract common color function and constants
- Use templates to reduce code duplication
With GothenburgBitFactory/taskwarrior#2519, all 'end of *' named dates have been changed to be the last minute of the respective date.
This caused the ':lastweek' hint to miss the last day of its range.
Closes#493
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Make installation of man pages configurable per section
Use configuration variable TIMEW_BINDIR
Update documentation
Closes#553
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Currently, if an AtomicFile is opened on a symlink, the AtomicFile would
end up overwriting the link. This change makes AtomicFiles operate on
the targets of the links and not the links themselves.
```
$ test/AtomicFileTest
1..22
ok 1 - AtomicFileTest: Shall not exists before finalize
ok 2 - AtomicFileTest: Shall exists after finalize
ok 3 - AtomicFileTest: Shall have the correct data
ok 4 - AtomicFileTest: Neither shall exist before finalize
ok 5 - AtomicFileTest: Both shall exists after finalize
ok 6 - AtomicFileTest: First file shall contain the correct data
ok 7 - AtomicFileTest: Second file shall contain the correct data
ok 8 - AtomicFileTest: Appending does not update original before finalize
ok 9 - AtomicFileTest: Finalizing updates the appended data
ok 10 - AtomicFileTest: Read from Atomicfile
ok 11 - AtomicFileTest: Read from Atomicfile should read unfinalized data
ok 12 - AtomicFileTest: Two AtomicFiles should access same temp file (part 1)
ok 13 - AtomicFileTest: Two AtomicFiles should access same temp file (part 2)
ok 14 - AtomicFileTest: Two AtomicFiles should access same temp file (part 3)
ok 15 - AtomicFileTest: File not removed before finalize
ok 16 - AtomicFileTest: File is removed after finalize
ok 17 - AtomicFileTest: writes to symlinks end up in target
ok 18 - AtomicFileTest: shall maintain symlink
ok 19 - AtomicFileTest: AtomicFile::write_raw throws on error # skip
ok 20 - AtomicFileTest: AtomicFile::finalize_all() throws on error # skip
ok 21 - AtomicFileTest: AtomicFile::reset clears failure state # skip
ok 22 - AtomicFileTest: AtomicFile::append throws on error # skip
ok 23 - AtomicFileTest: AtomicFile::append did not partially fill the file. # skip
ok 24 - AtomicFileTest: AtomicFile::append failures prevent finalization # skip
```
Fixes#546
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
Before this change, when AtomicFileTest had errors, there was no match for details:
```
$ test/problems --details test/all.log
Traceback (most recent call last):
File "test/problems", line 145, in <module>
details_errors[filename] += " - " + detail.match(line).group(1) + "\n"
AttributeError: 'NoneType' object has no attribute 'group'
```
Now the details are pulled out properly:
```
$ test/problems --details test/all.log
Failed:
AtomicFile.t (2):
- AtomicFile::write_raw throws on error
- AtomicFile::finalize_all() throws on error
Unexpected successes:
Skipped:
Expected failures:
```
Why these tests are failing on this particular host is a matter for another time...
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- Add CLI::getRange
- Make CLI::getTags return a set instead of a vector. This has the side effect that the tags are sorted now...
- Replace variable 'filter' by 'range' and 'tags'. Variable 'filter' was just a wrapper, better use the components directly
Use notations 'Clang'/'GCC', 'Asciidoctor', 'Make', 'Git', 'CMake' when referring to the tool, not the command
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Use emplace_back instead of push_back
Use 'nullptr'
Use function 'empty ()' instead of 'size () == 0'
Mark single-argument constructors as 'explicit'
Call static function correctly
- Remove unused includes
- Use '<..>' style consistently
- Strip any paths from include
- Replace deprecated C++ headers
- Sort includes according to LLVM rules
https://llvm.org/docs/CodingStandards.html#include-style
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Bump CMake to minimum version 3.8
- Set C++ standard to 17
- Remove CMAKE_LEGACY_CYGWIN_WIN32 compatibility mode
- Remove C++11 stuff
- Update documentation
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Add repository and license for fish completion
- Beautify repository URLs
- Updated texts
Relates to #535
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Replace tabs with spaces
- Use lowercase for CMake commands
- Unify alignment
- Remove superfluous empty line
- Add space after CMake command
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Main development branch is 'develop'.
Branch 'stable' always points to the latest release.
Closes#531
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
We need to set the value of `MANPATH` to the local man pages when running helper function 'run_cmd_wait_nofail'.
Use the already set Timewarrior environment for this.
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Fixed summary truncating annotations which are too long and consisting
of multibyte characters, by using UTF8 aware functions for measuring
length of the string and takeing a substring.
Signed-off-by: Maxim Beder <macsim.beder@gmail.com>
When calling summary command with :annotations hint, if the annotation
is longer than a certain length, it's going to be truncated. The issue
is that the length and truncation are done on a raw string without
considering UTF8 multibyte characters, so there are edge cases when an
annotation is truncated in the middle of a character creating an invalid
UTF8 string.
Added a test case for this scenario.
Signed-off-by: Maxim Beder <macsim.beder@gmail.com>
The workflow is triggered by a successful run of the test suite and creates a Docker image with a Timewarrior installation of the current branch (restricted to develop/stable)
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Query rule 'reports.<name>.range' for the specific default range of the report.
Use rule 'reports.range' to configure an overall default range for all reports.
Make internal reports 'summary', 'month', 'week', 'day', and 'gaps' use this feature.
Closes#477
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This patch checks if intervals are given on cli to 'timew export', and
if so will filter only those numbered IDs out from the db. This lets
the user that already knows the interval(s) they want to know about, to
ask for only those, without parsing the whole thing (similar to how we
can do this for taskwarrior IDs).
If both intervals and other filters -- time range or tags -- are given,
this is considered an error. There would seem to be little use to AND
or OR tags/ranges with IDs because anyone that knew IDs to request would
already know those IDs met their requirement.
Fixes#510
Code additions from @lauft PR notes (thanks!):
- factor out 'filtering' so we can do only one call to getTracked()
- simplify (tag || range) to .empty(), which already checks both
- error message phrasing
Signed-off-by: Scott Mcdermott <scott@smemsh.net>
- Replace unused return variables with '_'
- Use 'expected' and 'actual' for test values
- Add whitespace
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
The command timew help should redirect to the man tool.
Instead of testing that the header of the output matches some reg ex,
test that the outputs of `timew help` and `man` are equal
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
The error message may be different depending on the man tool used.
Therefore, instead of hard-coding it into the test, ensure it is the same as produced by the man command
Closes#512
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Use interval array to determine whether there is data to display
Move interval truncation outside the loop, combine/rework 'no data' messages
Close#450
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Needed to allow database to be kept on some network filesystems
(GothenburgBitFactory/libshared#70).
fixes#465
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- Restores behaviour which got lost when switching to the new interval filtering in 9968b9e9
- Add test for each command
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
With 179a6153, all 'end of' named dates point to the last second of the respective interval.
(see GothenburgBitFactory/taskwarrior#2519)
Redefine hint intervals in Timewarrior by 'start of' named dates, such that their ranges comprise the full interval as expected.
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- add config `reports.summary.ids` to toggle display of IDs
- add config `reports.summary.annotations` to toggle display of annotations
- add hints `:no-ids` and `:no-annotations` to override positive configs
Closes#474
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This eliminates the use of the naked "new" so that when the filters object is
destroyed, the filters are also freed.
This also eliminates a potential issue with binding an r-value reference to a
Range as a reference in IntervalFilterAllInRange.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
Replace in commands CmdAnnotate, CmdDefault, CmdContinue, CmdTag, and CmdUntag
Also in function domGet
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
A first-of interval filter is done when the first matching interval has been found.
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
An and-group interval filter accepts all intervals which are accepted by all filters in its group.
It is done, if one of the filters in its group is done.
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Replace getTracked in commands CmdSummary, CmdChart, CmdExport, CmdFill,
CmdReport, CmdTags, and CmdContinue. Also in functions domGet and autoFill
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
An id-set interval filter accepts all intervals, which contain all ids of the given id set.
This filter is done when all ids have been found.
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
An all-in-range interval filter accepts all intervals which intersect with the given range.
This filter is done if it encounters an interval with an end datetime before its range's start datetime.
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
An all-with-tags interval filter accepts all intervals which contain all tags of the given tag set.
This filter is never done, i.e. it will consume all intervals from the stream.
Relates to #468
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Fix `--fail-at-end` option
- Collect errors and print report at end
- Make variable `tests` an array, add safeguards
- Combine cases
- Make variables `dates`, `hours`, `minutes` an array, add `pad_with_zero` function
- Execute test with specific 'runtime', so it picks up fake time
- Python scripts are then executed as `faketime <date> python3 <test>`
- Shell scripts as `faketime <date> bash <test>`
- Everything else as `faketime <date> <test>`
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
1) Remove AtomicFile::impl::find and use std::find_if directly.
2) Remove static functions that take a string for path. Allow the compiler to
construct the Path object as necessary.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- Add documentation of `:all` hint
- Add `timew-hints` as `SEE ALSO` to `timew-ranges`
Related to #408
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
I left some unused varaibles in a new test functions after copy-paste.
This addresses @laufts comments on #423.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
It is not sufficient to stop looking for matching intervals if the
interval start time is before the filter. We really want to make sure
that we pick up any intervals that intersect with the filter.
Fixes bug introduced in (a98bd14 "Simplify getIntervalsById and
getTracked") as part of #423.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
The intent here is to make similar the implementations of
getIntervalsById and getTracked, since they are both gathering a
collection of intervals from the database, but they are just using a
different criteria for which ones to pull.
This also eliminates the use of std::deque.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This also installs asciidoctor 2.0.15 explicitly so that if the latest
is changed upstream the update-alternatives line will not break.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
Eliminates extra noise in the debug output. I.e. from #422 the original
report contained:
>> 2021-05.data: Deleted inc 20210511T161243Z # "TRACKER-6145"
>> 2021-05.data: Added inc 20210511T161243Z # "TRACKER-6145"
Which isn't doing anything.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This fixes an error where the latest interval, a non-synthetic interval,
is added to the synthetic array (and marked synthetic) if flatten() is
otherwise not able to convert it to a group of synthetic intervals.
When modify was attempting to edit this interval, it would fail since
synthetic intervals should not be written to the database unless the
database is being flattened and timewarrior believed the interval to be
modified was synthetic.
Closes#422
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
The Interval::dump() method will show if intervals are synthetic or not,
which can be useful when trying to determine why a comparison is
failing.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
The JSON library in libshared has functions to esacpe JSON's special
characters, but they are not used by default.
Closes#416
Related to #261
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
The bitwise or, `|` had higher precendence than the `>` test. Fixes the
following error:
not ok 4 - summary.t: Summary should work with :all hint
# FAIL: AssertionError on file test/summary.t line 213 in test_with_all_hint: 'self.assertIn("""':
# '
# Wk Date Day ID Tags Start End Time Total
# -- ---------- --- -- ---- -------- -------- ------- -------
# W13 2021-04-04 Sun @3 FOO 10:00:00 11:00:00 1:00:00 1:00:00
# W14 2021-04-05 Mon @2 BAR 10:00:00 11:00:00 1:00:00 1:00:00
# W14 2021-04-06 Tue @1 BAZ 10:00:00 11:00:00 1:00:00 1:00:00
#
# 3:00:00
# ' not found in '
# Wk Date Day ID Tags Start End Time Total
# --- ---------- --- -- ---- -------- -------- ------- -------
# W13 2021-04-04 Sun @3 FOO 10:00:00 11:00:00 1:00:00 1:00:00
# W14 2021-04-05 Mon @2 BAR 10:00:00 11:00:00 1:00:00 1:00:00
# W14 2021-04-06 Tue @1 BAZ 10:00:00 11:00:00 1:00:00 1:00:00
#
# 3:00:00
#
# '
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
The help.t test wants to verify that some of the man pages exist.
Therefore we need to make sure the documentation is built, otherwise:
$ git clean -ffdx .
$ cmake -DCMAKE_BUILD_TYPE=Debug .
$ make test
Will fail some of the help.t tests.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This replaces the generation of man pages on project setup
by a on-demand generation via asciidoctor.
An exception are the man pages for the commands `day`, `month`, and `week`
which are simply redirects to the man page `timew-chart.1`. Those are now
static files in the Timewarrior repository.
A CMake find module to detect asciidoctor was added.
If asciidoctor is found, the targets `doc`, `man1`, and `man7` are created.
Those targets are also added to the default build target.
If asciidoctor is not available, the target `doc` is available, but it only
emits a message to install asciidoctor first.
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Compatibility with CMake < 2.8.12 will be removed from a future version of CMake.
According to our test images all supported distributions have CMake > 3
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
See #380. We will include the test suite in the release tarball so the Gentoo maintainers can run it and report back.
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Python added Thread.is_alive() in 2.6 and removed Thread.isAlive() in
3.9.
This change is needed to run the tests with Python 3.9.
https://bugs.python.org/issue37804
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
It was possible for `summary` command, when used with the :all hint, to
skip over any intervals that start later than the first interval in the
database.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- Content of `NEWS` is either already in README.md or file just echoes Timewarriors release notes on github
- `COPYING` is identical to `LICENSE`
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
fixup! Drop 'NEWS'
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- This is meant as a temporary fix until Timewarrior can handle intervals regardless of start time
- Closes#364
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
There are several instances where the "total" reported in the interval
summary is confusing because the summarize function would walk backward
and add all intervals with the same set of tags.
Closes#248 and #308
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- It seems that recent changes made the `stop` command faster such that these tests aborted with "The end of a date range must be after the start."
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Compute the set difference between the latest interval's tag set and the given tag set
- If no tags given, the difference is set to `{}`
- In case of an empty difference, close the current open interval, apply exclusions and update the database
- In case of a non-empty difference, just add a new open interval and let the overlap resolution do the job...
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- The given set of tags must be a subset of the latest interval's tag set (this includes the empty case)
- If not a subset, throw an error and show the first non-matching tag
- This also prevents the stop command from doing any work on the database
- Closes#280
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Use default range starting at `now`
- Add check for no datetime given (rare case of e.g. `timew stop :all`)
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
I had a broken symbolic link in my extensions directory. When I ran
`timew diag` it would simply print on the screen:
```
stat error 2: No such file or directory
```
After this change, there is more context information about the source of
the error:
```
timew 1.3.0
Platform: Linux
Compiler:
Version: 7.5.0
Caps: +stdc +stdc_hosted +LP64 +c8 +i32 +l64 +vp64 +time_t64
Compliance: C++11
Build Features
Built: Aug 14 2020 05:57:06
Commit: 6fe15d26
CMake: 3.10.2
Build type: Debug
Configuration
TIMEWARRIORDB: -
Cfg: /home/sruffell/.timewarrior/timewarrior.cfg (-rw- 0 bytes)
Database: /home/sruffell/.timewarrior (drwx 4096 bytes)
$EDITOR: vim
Color theme: Built-in default
00 01 02 03 04 05 06 07 08 09 10 11 12
Extensions
Location: /home/sruffell/.timewarrior/extensions (drwx 4096 bytes)
/home/sruffell/.timewarrior/extensions/tsheet (stat error 2: No such file or directory)
```
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This is particularly bad when called from the Database::modifyInterval
call, since the delete may fail, but then the addInterval will proceed.
Closes#319
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
I would like to use TempDir for the Datafile test in order to cleanup
any datafiles created as part of the test.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
If calling undo on an operation the removes many entries from the
datafiles, there would be many 0 length size files remaining in the data
directory. Now they will be removed if they are empty so they will not
longer need to be checked when parsing the database.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
Allows the user to specify a maximum number of entries to store in the
undo file. By default the behavior is unchanged, and the file will grow
unbounded without user intervention.
journal.size = 0 will disable storing any entries, journal.size < 0
indicates that the size of the journal should be unlimited (the
default), otherwise it indicates the number of entries to store.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- This also handles the case when it is called with the `:all` hint
- When called with a range, the `track` command is recommended
- There is no forwarding to `track`
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
Move the adjustment of a new open interval that is enclosed by the
current open interval into the validation processing, where the other
overlap resolution takes place.
This will allow the start command to honor the :adjust flag when
starting a new interval that predates the current open interval.
Closes#326
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
It was possible previously to start an interval with a filter earlier
than the current filter, and if the tags matched, the command would
report success without actually moving the start time.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
Since the Intervals are all in order, we can use getTracked directly to
get overlapping intervals without the need to copy the Intervals into
another vector.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- Add tests for JSON output
- Separate different test scenarios
- Optimize JSON output in `TagInfoDatabase::toJson ()`
- Closes#325
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- This adds the last bits to the PR started by Christian Roesch:
- Some code formatting
- Specifying both id(s) and tag(s) is an error
- Clear range for tag filter: The range is meant to set the new interval's range, not the filter's
- Added tests
- Overhauled test using relative times and testing exported intervals instead of command line output
- Closes#241
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Only an open interval can truncate another open interval.
Otherwise the `:adjust` hint has to be applied
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Filter shall be taken as is, not changed
- If there is a problem, the functions consuming the filter have to be adapted, not the filter
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
- Add DatetimeParser::parse_range: If a date contains no time, it is assumed to be a fixed range, else an open range starting at given datetime
- Add tests for summary with named dates 'yesterday' and 'today'
- Remove closing of filter in CmdSummary.cpp
- Closes#333
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
In order to keep the database consistent, we really want all the
AtomicFiles to be finalized as a group. This will prevent an inopportune
signal from interrupting this process.
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
- This file was development only, now any other test file can serve as template for new tests
- Closes#303
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
The json::object pointer was allocated in the parse function but never
freed.
The way timwarrior is used currently, this leak does not cause any
problems, but...
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
When the Lexer breaks a line into tokens, it also wants to return the
type of the token. This information isn't used by the IntervalFactory
and it slows down the operation since dates end up being parsed at least
twice, once by the Lexer to determine that the string is a date, then
again in the IntervalFactory to actually construct the Date.
Before are the before and after results when exporting a database with
100 lines. The number of instructions executed went from roughly 31,552,467 to
12,952,372 on debug builds. Release builds saw a change from around 14K
to 7K instructions.
Before:
$ rm -fr ~/.timewarrior; src/timew :yes >/dev/null; for x in {100..1}; do src/timew start ${x}sec ago proj_${x} >/dev/null; done;
$ sudo chrt -f 99 valgrind --tool=callgrind --callgrind-out-file=callgrind.out src/timew export >/dev/null
==20888== Callgrind, a call-graph generating cache profiler
==20888== Copyright (C) 2002-2017, and GNU GPL'd, by Josef Weidendorfer et al.
==20888== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==20888== Command: src/timew export
==20888==
==20888== For interactive control, run 'callgrind_control -h'.
==20888==
==20888== Events : Ir
==20888== Collected : 31552467
==20888==
==20888== I refs: 31,552,467
After:
$ sudo chrt -f 99 valgrind --tool=callgrind --callgrind-out-file=callgrind.out src/timew export >/dev/null
==24088== Callgrind, a call-graph generating cache profiler
==24088== Copyright (C) 2002-2017, and GNU GPL'd, by Josef Weidendorfer et al.
==24088== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==24088== Command: src/timew export
==24088==
==24088== For interactive control, run 'callgrind_control -h'.
==24088==
==24088== Events : Ir
==24088== Collected : 12952372
==24088==
==24088== I refs: 12,952,372
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
2020-05-10 21:16:08 +02:00
293 changed files with 14000 additions and 5356 deletions
@ -8,13 +8,13 @@ Anyone can contribute, and everyone is encouraged to do so.
Here are the different ways you might conѕider contributing:
1. Reviews
1. Bug reports
1. Feature requests
1. Code contribution
2. Bug reports
3. Feature requests
4. Code contribution
Please read the respective section below about the details.
Otherwise you can spread the word and recommend Timewarrior to your friends and colleagues.
Otherwise, you can spread the word and recommend Timewarrior to your friends and colleagues.
## Reviews
@ -29,7 +29,7 @@ It is also the quickest way to get help, or confirm a bug.
Review documentation: there are man pages, online articles, tutorials and so on, and these may contain errors, or they may not convey ideas in the best way.
You can help improve it.
Documentation is a separate effort from the codebase, and includes all web sites, and all are available using git.
Documentation is a separate effort from the codebase, and includes all websites, and all are available using Git.
Take a look at the bug database, and help triage the bug list.
Bug triage is very useful and much needed.
@ -43,7 +43,7 @@ Review the source code, and point out inefficiencies, problems, unreadable funct
## Bug reports
Before you submit a bug report, make sure you are using the latest version of Timewarrior.
Also please take your time and scan the current bug tickets on our [Github issue tracker](https://github.com/GothenburgBitFactory/timewarrior/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Abug) whether your issue has already been reported.
Also, please take your time and scan the current bug tickets on our [GitHub issue tracker](https://github.com/GothenburgBitFactory/timewarrior/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Abug) whether your issue has already been reported.
When you submit a bug report, be precise and put as much information into your bug report as possible.
You should at least provide
@ -64,7 +64,7 @@ An example:
## Feature requests
As for bug reports, you should check our [Github issue tracker](https://github.com/GothenburgBitFactory/timewarrior/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Aenhancement) whether your feature has already been requested.
As for bug reports, you should check our [GitHub issue tracker](https://github.com/GothenburgBitFactory/timewarrior/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Aenhancement) whether your feature has already been requested.
When you submit a feature request, provide a use case which captures the overall intention of your feature, not the technical implementation.
@ -85,9 +85,9 @@ Plus, you might get your feature implemented.
There are different ways you can contribute code to the project:
1. Add extensions
1. Add tests
1. Fix bugs
1. Add features
2. Add tests
3. Fix bugs
4. Add features
### Extensions
@ -96,12 +96,12 @@ Extensions are standalone programs or scripts that consume Timewarrior data outp
Extensions are the easiest way to contribute as you only need to adhere to the extension API, but are otherwise free in your choice of programming language and style.
Consult the [documentation](https://taskwarrior.org/docs/timewarrior/api.html) on how you can use the extension API.
Consult the [documentation](https://timewarrior.net/docs/api.html) on how you can use the extension API.
### Tests, Bug-fixes and Features
In general your contributions have to be associated with an issue on our [Github issue tracker](https://github.com/GothenburgBitFactory/timewarrior/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen).
In general your contributions have to be associated with an issue on our [GitHub issue tracker](https://github.com/GothenburgBitFactory/timewarrior/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen).
See the sections above on how to submit bug reports and feature requests.
Code contributions are only accepted as pull-requests.
@ -123,32 +123,32 @@ By contributing, you are declaring that you have the right to submit the code un
## How to make a pull-request
The main branch for development is named `dev`.
The main branch for development is named `develop`.
This is the branch where your changes must go.
The `master` branch always points to the latest release.
The `stable` branch always points to the latest release.
No development takes place here.
To make a pull request you need to have a Github account.
To make a pull request you need to have a GitHub account.
1. Fork the [Timewarrior repository](https://github.com/GothenburgBitFactory/timewarrior) on Github.
1. Checkout the development branch.
1. Fork the [Timewarrior repository](https://github.com/GothenburgBitFactory/timewarrior) on GitHub.
2. Checkout the development branch.
$ git checkout dev
1. Create a feature branch.
3. Create a feature branch.
$ git checkout -b feature_branch
1. Commit your changes, and finally push to the remote repository.
4. Commit your changes, and finally push to the remote repository.
Use a commit message that matches the prevailing format. (See `git log` for examples.)
Five more variables can customize the installation process.
The following table lists them and their default values:
| Variable | Default Value |
|-----------------|-------------------|
| `TIMEW_BINDIR` | `bin` |
| `TIMEW_DOCDIR` | `share/doc/timew` |
| `TIMEW_MANDIR` | `share/man` |
| `TIMEW_MAN1DIR` | `share/man/man1` |
| `TIMEW_MAN7DIR` | `share/man/man7` |
On FreeBSD or DragonFly BSD systems, the `share/` directory is omitted for the `TIMEW_MAN*DIR` variables.
The `TIMEW_*` variables are combined with the value of `CMAKE_INSTALL_PREFIX` to get the absolute paths.
# Updating Timewarrior build
This section concerns itself with the description of the procedure needed to update the local Timewarrior build from the 'timew' git repository.
To update the local Timewarrior build, you need to update the git repository, including the `src/libshared` submodule.
To do that, run:
To update the local Timewarrior build, you need to update the Git repository, including the `src/libshared` submodule, run:
$ git pull --recurse-submodules
$ git submodule update
At this point you have the fully updated sources at your disposal and you can update your local build following the regular build instructions:
At this point you have the fully updated sources at your disposal, and you can update your local build following the regular build instructions:
$ cmake .
$ make
@ -107,7 +100,7 @@ To uninstall Timewarrior, remove the files listed in the `install_manifest.txt`
Timewarrior has dependencies that are detected by CMake in almost all cases, but there are situations and operating systems that mean you will need to offer a little help.
If Timewarrior will not build on your system, first take a look at the Operating System notes below.
If Timewarrior does not build on your system, first take a look at the Operating System notes below.
If this doesn't help, then go to the Troubleshooting section, which includes instructions on how to contact us for help.
Timewarrior is a time tracking utility that offers simple stopwatch features as well as sophisticated calendar-based backfill, along with flexible reporting.
It is a portable, well supported and very active Open Source project.
It is a portable, well-supported and very active Open Source project.
Please visit [timewarrior.net](https://timewarrior.net/docs/) for extensive documentation, downloads, news and more.
Build Timewarrior, optionally run the test suite (note: the tarball does not contain tests), and install it.
cmake -DCMAKE_BUILD_TYPE=release
make
[make test]
sudo make install
```
tar xzf timew-1.8.0.tar.gz
cd timew-1.8.0
```
Build Timewarrior, optionally run the test suite, and install it.
```
cmake -DCMAKE_BUILD_TYPE=release .
make
[make test]
sudo make install
```
This copies files into the right place (default under `/usr/local`), and installs man pages.
Add the optional parameter `-DCMAKE_INSTALL_PREFIX=/path/to/your/install/location` to the `cmake` command if you want to install Timewarrior at a location other than `/usr/local`.
The `make install` command may not require `sudo` depending on your choice of install location.
You'll find all the details at [timewarrior.net/docs/](https://timewarrior.net/docs/).
Timewarrior has a lively community on many places on the internet.
The project has its own Twitter account, and shares community spaces on IRC and Discord with [Taskwarrior](https://github.com/GothenburgBitFactory/taskwarrior).
There you will find the documentation, downloads, news and more.
Best place to ask questions is our [discussions forum on GitHub](https://github.com/GothenburgBitFactory/timewarrior/discussions).
For other support options, take a look at [timewarrior.net/support](https://timewarrior.net/support)
[](https://github.com/GothenburgBitFactory/timewarrior/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
Your contributions are especially welcome.
Whether it comes in the form of code patches, ideas, discussion, bug reports, encouragement or criticism, your input is needed.
Contributions are greatly appreciated.
Whether in the form of code patches, ideas, discussion, bug reports, encouragement or criticism, we need you!
For support options, take a look at [CONTRIBUTING.md](CONTRIBUTING.md) or visit [taskwarrior.org](https://taskwarrior.org/support).
For support options, take a look at [CONTRIBUTING.md](CONTRIBUTING.md) or visit [timewarrior.net](https://timewarrior.net/support).
Visit [Github](https://github.com/GothenburgBitFactory/timewarrior) and participate in the future of Timewarrior.
Visit [GitHub](https://github.com/GothenburgBitFactory/timewarrior) and participate in the future of Timewarrior.
message(WARNING"Enabling -std=c++0x draft compile flag. Your compiler does not support the standard '-std=c++11' option. Consider upgrading.")
set(_CXX11_FLAGS"-std=c++0x")
elseif(_HAS_GNU0X)
message(WARNING"Enabling -std=gnu++0x draft compile flag. Your compiler does not support the standard '-std=c++11' option. Consider upgrading.")
set(_CXX11_FLAGS"-std=gnu++0x")
else(_HAS_CXX11)
message(FATAL_ERROR"C++11 support missing. Try upgrading your C++ compiler. If you have a good reason for using an outdated compiler, please let us know at support@gothenburgbitfactory.org.")
The completion scripts here are taken from separate projects.
Issues and pull-requests regarding those should go there.
The updated version of each script will then be included here.
If you are missing a completion, feel free to contribute.
* `timew-completion.bash` is taken from https://github.com/lauft/timew-bashcompletion which is released under [MIT license](https://github.com/lauft/timew-bashcompletion/blob/master/LICENSE)
* `timew.fish` is taken from [pfmephisto/timew-fishcompletion](https://github.com/pfmephisto/timew-fishcompletion) which is released under [MIT license](https://github.com/pfmephisto/timew-fishcompletion/blob/main/LICENSE)
* `timew-completion.bash` is taken from [lauft/timew-bashcompletion](https://github.com/lauft/timew-bashcompletion) which is released under [MIT license](https://github.com/lauft/timew-bashcompletion/blob/master/LICENSE)
* `timew.zsh` is taken from [ianmkenney/timewarrior_zsh_completion](https://github.com/ianmkenney/timewarrior_zsh_completion) which is released under [MIT license](https://github.com/ianmkenney/timewarrior_zsh_completion/blob/main/LICENSE)
The holiday files were created by the `refresh` script using data from https://holidata.net.
The holiday files can be updated using the command:
The holiday files were created by the `refresh` script using data from [holidata.net](https://holidata.net).
They can be updated using the following command:
$ ./refresh
```shell
$ ./refresh
```
This updates all present holiday files with holiday data for the current and the following year (default).
If you need another locale (for example `sv-SE`), do this:
$ ./refresh --locale sv-SE
```shell
$ ./refresh --locale sv-SE
```
This creates a file `holidays.sv-SE` containing holiday data for the current and following year.
The id for the locale is composed from the [ISO 639-1 language code](https://en.wikipedia.org/wiki/ISO_639-1) and the [ISO 3166-1 alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
The id for the locale is composed of the [ISO 639-1 language code](https://en.wikipedia.org/wiki/ISO_639-1) and the [ISO 3166-1 alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
If you need a specific locale region, do this:
$ ./refresh --locale de-CH --region BE
```shell
$ ./refresh --locale de-CH --region BE
```
For regions use the corresponding [ISO 3166-2 code for principal subdivisions](https://en.wikipedia.org/wiki/ISO_3166-2).
To specify a set of years to update, do this:
$ ./refresh --locale en-US --year 2018 2019 2020
```shell
$ ./refresh --locale en-US --year 2020 2021 2022
```
If the locale is not yet supported by holidata.net, or there is no data available for the requested year, you will see an error.
If the locale is not yet supported by [holidata.net](https://holidata.net), or there is no data available for the requested year, you will see an error.
A chart summarizes the tracked and untracked time with colored blocks drawn on a timeline.
It accepts date ranges and tags for filtering.
There are three types:
.BR day ", " week ", and " month
with their respective commands.
The
.BI reports. <type> .range
configuration setting overrides the default date range.
There are three types: *day*, *week*, and *month* with their respective commands.
The **reports.**__<type>__**.range** configuration setting overrides the default date range.
One can override the global default date range with the **reports.range** configuration.
For more details, and precise times, use the 'summary' report.
.TP
.B month
*month*::
The month command shows a chart depicting a single month (current month by default).
The default date range shown is
.BR :month .
.
.TP
.B week
The default date range shown is *:month*.
*week*::
The week command shows a chart depicting a single week (current week by default).
The default date range shown is
.BR :week .
.
.TP
.B day
The default date range shown is *:week*.
*day*::
The day command shows a chart depicting a single day (today by default).
The default date range shown is
.BR :day .
.
.SH CONFIGURATION
.IR <type> " is one of"
.BR month ", " week ", " day "."
.TP
.BI reports. <type> .cell
.RS
The default date range shown is *:day*.
== CONFIGURATION
_<type>_ is one of **month**, **week**, **day**.
**reports.**__<type>__**.cell**::
Determines how many minutes are represented by a single character cell, for the charts.
The value must be greater than '0'.
A value of '15' means that an hour is represented by 60/15, or 4 character cells.
Suitable values are the divisors of 60 (30, 20, 15, 12, ...).
.br
Default value is '15'.
.RE
.TP
.BI reports. <type> .day
.RS
**reports.**__<type>__**.day**::
Determines whether the current day of the month is shown at left margin.
.br
Default value is 'yes'.
.RE
.TP
.BI reports. <type> .holidays
.RS
**reports.**__<type>__**.holidays**::
Determines whether relevant holidays are shown beneath the report.
.br
Default value is 'yes'.
.RE
.TP
.BI reports. <type> .hours
.RS
Determines how the <type> report shows all the hours in a day ('all'), or is limited to only hours where data is tracked ('auto').
.br
**reports.**__<type>__**.hours**::
Determines how the <type> report shows all the hours in a day ('all'), or is limited to only hours when data is tracked ('auto').
Default value is 'all'.
.RE
.TP
.BI reports. <type> .lines
.RS
**reports.**__<type>__**.lines**::
Determines how many lines are used to render each day on the <type> report.
.br
Default value is '1'.
.RE
.TP
.BI reports. <type> .month
.RS
**reports.**__<type>__**.month**::
Determines whether the current month is shown at left margin.
.br
Default value is 'yes'.
.RE
.TP
.BI reports. <type> .range
.RS
**reports.**__<type>__**.range**::
For reports that show a range of data, this setting will override the default value.
The value should be a range hint, see
.BR timew-hints (7).
.RE
.TP
.BI reports. <type> .spacing
.RS
**timew-hints**(7).
**reports.**__<type>__**.spacing**::
Specifies how many spaces are inserted between the hours in the <type> report exclusions.
A value of '0' yields a more compact report.
.br
Default value is '1'.
.RE
.TP
.BI reports. <type> .axis
.RS
The value 'internal' puts the hour markers (time line at the top) inside the exclusion blocks, 'external' puts the hour markers in a separate line; additional values might be defined in the future.
.br
**reports.**__<type>__**.axis**::
The value 'internal' puts the hour markers (timeline at the top) inside the exclusion blocks, 'external' puts the hour markers in a separate line; additional values might be defined in the future.
Default is 'internal' for the day report and 'external' for other reports.
.br
.RE
.TP
.BI reports. <type> .summary
.RS
**reports.**__<type>__**.summary**::
Determines whether the hours summary is shown.
.br
Default value is 'on'.
.RE
.TP
.BI reports. <type> .totals
.RS
**reports.**__<type>__**.totals**::
Determines whether the time totals are shown for each day on the report.
.br
Default value is 'on'.
.RE
.TP
.BI reports. <type> .week
.RS
**reports.**__<type>__**.week**::
Determines whether the current week number is shown at left margin.
.br
Default value is 'yes'.
.RE
.TP
.BI reports. <type> .weekday
.RS
**reports.**__<type>__**.weekday**::
Determines whether the current weekday is shown at left margin.
.br
Default value is 'yes'.
.RE
.
.SH HINTS
.TP
.B :blank
**tags.**__<tag>__**.color**::
Assigns a specific foreground and background color to a tag, instead of the default color palette determined by your current theme.
Examples of valid colors include 'white', 'gray8', 'black on yellow', and 'rgb345'.
== HINTS
*:blank*::
The ':blank' hint causes only the excluded time to be shown, with no tracked time.
This can be used to see the exclusions.
.TP
.B :ids
*:ids*::
The ':ids' hint causes the intervals to be displayed with their ids
.
.SH EXAMPLES
Charts accept date ranges and tags for filtering, or shortcut hints:
.RS
$ timew month 1st - today
.br
$ timew week FOO BAR
.br
$ timew day :week
.RE
.
.SH "SEE ALSO"
.BR timew-day (1),
.BR timew-month (1),
.BR timew-summary (1),
.BR timew-week (1)
== EXAMPLES
Charts accept date ranges and/or tags, or ids for filtering:
$ timew month 1st - today
$ timew week FOO BAR
$ timew day @3 @4
See **timew-ranges**(7) and **timew-hints**(7) on the different ways to provide date ranges.
The 'continue' command is used to resume tracking specified by a closed interval.
This command is a convenient way to resume work without re-entering the tags.
The interval to be resumed can be specified either by its id or by a set of tags.
Specifying multiple ids or both ids and tags will result in an error.
When given a set of tags, the first interval matching it will be taken as a blueprint for the new interval.
When given neither id nor tags, the first interval in the database is taken.
When no datetime or range given, the new interval is started at the current time.
== EXAMPLES
Using the 'summary' command and specifying the ':ids' hint shows interval IDs.
Consider the following intervals:
$ src/timew summary :ids
Wk Date Day ID Tags Start End Time Total
W23 2020-06-04 Thu @4 BAR 13:00:00 14:00:00 1:00:00
@3 BAR, FOO 14:00:00 15:00:00 1:00:00
@2 BAR, BAZ, FOO 15:00:00 16:00:00 1:00:00
@1 FOO 16:00:00 17:00:00 1:00:00 4:00:00
4:00:00
Simple continue::
+
$ timew continue
The 'continue' command creates a new open interval, starting now, with tag 'FOO'
Continue an interval via id::
+
$ timew continue @3
The 'continue' command creates a new open interval, starting now, with tags 'BAR' and 'FOO'.
Continue an interval via tag set::
+
$ timew continue FOO BAR
The 'continue' command creates a new open interval, starting now, with tags 'FOO', 'BAR', and 'BAZ'.
Note that the first matching interval (here '@2') is taken as a blueprint for the new interval, although '@3' would have been a perfect match for the given tag set.
The command 'timew continue BAR' would have the same effect.
This means that there is no way to continue '@4' via a tag set.
Continue an interval at a specific date & time::
+
$ timew continue @4 19:00 (1)
$ timew continue FOO 19:00 (2)
The 'continue' command creates a new open interval
1. with tag 'BAR' (as specified by '@4') and start time '19:00'.
2. with tag 'FOO' (as specified by '@1') and start time '19:00'.
Continue an interval with a specific range::
+
$ timew continue @4 19:00 - 20:00 (1)
$ timew continue FOO 19:00 - 20:00 (2)
The 'continue' command creates a new closed interval
1. with tag 'BAR' (as specified by '@4'), start time '19:00', and end time '20:00'.
2. with tag 'FOO' (as specified by '@1') and start time '19:00', and end time '20:00'.
This command shows details about your version of Timewarrior, your platform, how it was built, compiler features, configuration, file access, extensions and more.
The purpose of this command is to help diagnose configuration problems and provide supplemental information when reporting a problem.
The 'modify' command is used to change range of an interval.
Using the 'start' or 'end' subcommand, one can either specify a new start or end date respectively, or with the 'range' subcommand, change the complete range.
The interval to be modified is specified via its id.
If the resulting interval overlaps with an existing interval, the command will return an error.
One can add the ':adjust' hint to force an overwrite in this case.
See **timew-summary**(1) on how to retrieve the interval id.
== EXAMPLES
*Modify the start date of an interval*::
+
$ timew modify start @3 2020-12-28T17:00
+
This sets the start of interval '@3' to '17:00' of date '2020-12-28'.
If this datetime is after the end of the interval, the command will return an error.
*Modify the end date of an interval*::
+
If the interval to be modified has the same date as today, it can be omitted:
+
$ timew modify end @3 18:00
+
Similar to when modifying the interval start, the end datetime has to be after the start datetime.
*Modify the range of an interval*::
+
Instead of modifying start and end separately, those can be combined into a single call of the 'range' subcommand:
+
$ timew modify range @3 2020-12-28T17:00 - 2020-12-28T18:00
+
As in the examples above, the date portion can be omitted, if the date of the interval is today.
It allows you to easily track your time and generate summary reports.
This is a reference, not a tutorial.
If you are looking for a tutorial, check the online documentation here:
[source]
----
https://timewarrior.net/docs/
----
When run without arguments or options, the default command is run, which indicates whether there is any active tracking, and if so, shows a summary and exits with code 0.
If there is no active time tracking, exit code is 1.
== OPTIONS
*--version*::
Display Timewarrior version information
*--help*::
Display Timewarrior usage information
== Timewarrior commands
Timewarrior supports many commands.
Alphabetically:
*timew-annotate*(1)::
Add annotation to intervals
*timew-cancel*(1)::
Cancel time tracking
*timew-config*(1)::
Get and set Timewarrior configuration
*timew-continue*(1)::
Resume tracking of existing interval
*timew-day*(1)::
Display day chart
*timew-delete*(1)::
Delete intervals
*timew-diagnostics*(1)::
Show diagnostic information
*timew-export*(1)::
Export tracked time in JSON
*timew-extensions*(1)::
List available extensions
*timew-get*(1)::
Display DOM values
*timew-help*(1)::
Display help
*timew-join*(1)::
Join intervals
*timew-lengthen*(1)::
Lengthen intervals
*timew-modify*(1)::
Change start or end time of an interval
*timew-month*(1)::
Display month chart
*timew-move*(1)::
Change interval start-time
*timew-report*(1)::
Run an extension report
*timew-resize*(1)::
Set interval duration
*timew-retag*(1)::
Replace tags in intervals
*timew-shorten*(1)::
Shorten intervals
*timew-show*(1)::
Display configuration
*timew-split*(1)::
Split intervals
*timew-start*(1)::
Start time tracking
*timew-stop*(1)::
Stop time tracking
*timew-summary*(1)::
Display a time-tracking summary
*timew-tag*(1)::
Add tags to intervals
*timew-tags*(1)::
Display a list of tags
*timew-track*(1)::
Add intervals to the database
*timew-undo*(1)::
Undo Timewarrior commands
*timew-untag*(1)::
Remove tags from intervals
*timew-week*(1)::
Display week chart
== MORE EXAMPLES
For examples please see the online documentation at:
https://timewarrior.net/docs/
Note that the online documentation is often more detailed and more current than this man page.
It allows you to easily track your time and generate summary reports.
.
This is a reference, not a tutorial.
If you are looking for a tutorial, check the online documentation here:
.br
https://taskwarrior.org/docs/timewarrior
.br
When run without arguments or options, the default command is run, which indicates whether there is any active tracking, and if so, shows a summary, then exits with a code 0.
If there is no active time tracking, exit code is 1.
.
.SHOPTIONS
.TP
.B\-\-version
.RS
Displays TimeWarrior version information
.RE
.TP
.B\-\-help
.RS
Display TimeWarrior usage information
.RE
.
.SH"TIMEWARRIOR COMMANDS"
Timewarrior supports many commands.
Alphabetically:
.
.TP
.BRtimew-annotate(1)
.RS
Add annotation to intervals
.RE
.TP
.BRtimew-cancel(1)
.RS
Cancel time tracking
.RE
.TP
.BRtimew-config(1)
.RS
Get and set Timewarrior configuration
.RE
.TP
.BRtimew-continue(1)
.RS
Resume tracking of existing interval
.RE
.TP
.BRtimew-day(1)
.RS
Display day chart
.RE
.TP
.BRtimew-delete(1)
.RS
Delete intervals
.RE
.TP
.BRtimew-diagnostics(1)
.RS
Show diagnostic information
.RE
.TP
.BRtimew-export(1)
.RS
Export tracked time in JSON
.RE
.TP
.BRtimew-extensions(1)
.RS
List available extensions
.RE
.TP
.BRtimew-get(1)
.RS
Display DOM values
.RE
.TP
.BRtimew-help(1)
.RS
Display help
.RE
.TP
.BRtimew-join(1)
.RS
Join intervals
.RE
.TP
.BRtimew-lengthen(1)
.RS
Lengthen intervals
.RE
.TP
.BRtimew-modify(1)
.RS
Change start or end time of an interval
.RE
.TP
.BRtimew-month(1)
.RS
Display month chart
.RE
.TP
.BRtimew-move(1)
.RS
Change interval start-time
.RE
.TP
.BRtimew-report(1)
.RS
Run an extension report
.RE
.TP
.BRtimew-resize(1)
.RS
Set interval duration
.RE
.TP
.BRtimew-shorten(1)
.RS
Shorten intervals
.RE
.TP
.BRtimew-show(1)
.RS
Display configuration
.RE
.TP
.BRtimew-split(1)
.RS
Split intervals
.RE
.TP
.BRtimew-start(1)
.RS
Start time tracking
.RE
.TP
.BRtimew-stop(1)
.RS
Stop time tracking
.RE
.TP
.BRtimew-summary(1)
.RS
Display a time-tracking summary
.RE
.TP
.BRtimew-tag(1)
.RS
Add tags to intervals
.RE
.TP
.BRtimew-tags(1)
.RS
Display a list of tags
.RE
.TP
.BRtimew-track(1)
.RS
Add intervals to the database
.RE
.TP
.BRtimew-undo(1)
.RS
Undo Timewarrior commands
.RE
.TP
.BRtimew-untag(1)
.RS
Remove tags from intervals
.RE
.TP
.BRtimew-week(1)
.RS
Display week chart
.RE
.
.SH"MORE EXAMPLES"
.
For examples please see the online documentation starting at:
.
.RS
<https://taskwarrior.org/docs/timewarrior/>
.RE
.
Note that the online documentation can be more detailed and more current than this man page.
.
.SHFILES
.
.TP
~/.timewarrior/timewarrior.cfg
User configuration file.
.
.TP
~/.timewarrior/data/YYYY-MM.data
Time tracking data files.
.
.SH"CREDITS & COPYRIGHTS"
Copyright (C) 2015 \- 2018 T. Lauf, P. Beckingham, F. Hernandez.
.br
Timewarrior is distributed under the MIT license.
See https://www.opensource.org/licenses/mit-license.php for more information.
.
.SH"FURTHER DOCUMENTATION"
For more information regarding Timewarrior, see the following:
.
.TP
The official site at <https://timewarrior.net>
.
.TP
The official code repository at <https://github.com/GothenburgBitFactory/timewarrior>
.
.TP
You can contact the project by emailing <support@gothenburgbitfactory.org>
.
.SH"REPORTING BUGS"
.TP
Bugs in Timewarrior may be reported to the issue-tracker at <https://github.com/GothenburgBitFactory/timewarrior/issues>
Timewarrior stores its configuration in the user's home directory in _~/.timewarrior/timewarrior.cfg_ on non-Unix systems (e.g. Windows).
On Unix systems, XDG Base Directory specification is supported, if _~/.timewarrior_ directory doesn't exist
(old config directory is still supported and has precedence over XDG BD compliant locations).
This means configuration is stored in _$XDG_CONFIG_HOME/timewarrior/timewarrior.cfg_, which defaults to _~/.config/timewarrior/timewarrior.cfg_ if _$XDG_CONFIG_HOME_ environment variable is not specified.
Those wanting to migrate their data to a new directory scheme, might do that with following shell snippet:
This file contains a mix of rules and configuration settings.
Note that the TIMEWARRIORDB environment variable can be set to override this location.
The values 'true', '1', 'y', 'yes' and 'on' are all equivalent and enable a setting.
Any other value means disable the setting.
Default values may be overridden by timewarrior.cfg values, which may in turn be overridden on the command line using: **rc.**__<name>__**=**__<value>__
The Timewarrior rule system reads your ~/.timewarrior/timewarrior.cfg file and
uses the combination of configuration settings and logic within to:
The Timewarrior rule system reads your timewarrior.cfg file and uses the combination of configuration settings and logic within to:
- Define configuration and customization details
- Define tags, exclusions, constraints
- Define various policies
The rules are a mechanism to apply late-bound logic and data to various
functions. Whenever data changes, the rule system is run, which will run each
rule in turn, if it applies, going from top to bottom in the rules file. There
are no chained rules, but errors will be able to terminate rule processing and
program execution.
On non-Unix systems config file is expected in ~/.timewarrior directory.
On Unix systems, if legacy ~/.timewarrior directory doesn't exist, config is read from $XDG_CONFIG_HOME/timewarrior directory (if not specified, $XDG_CONFIG_HOME defaults to ~/.config).
As much functionality as possible is to be deferred to the rules system, which
will initially be minimal, but grow to be come more capable.
The rules are a mechanism to apply late-bound logic and data to various functions.
Whenever data changes, the rule system is run, which will run each
rule in turn, if it applies, going from top to bottom in the rules file.
There are no chained rules, but errors will be able to terminate rule processing and program execution.
As much functionality as possible is to be deferred to the rules system, which will initially be minimal, but grow to become more capable.
Format
------
The rules are written as UTF8 text in the ~/.timewarrior/timewarrior.cfg text
file. Other rules files may be included:
The rules are written as UTF8 text in the timewarrior.cfg text file.
Other rules files may be included:
import /path/to/other/rule/file
@ -29,8 +29,7 @@ The syntax of rules is Python-like, in that indentation is significant.
Types of Rules
--------------
There are several different types of rules, for example there is the rule that
defines all exclusions:
There are several different types of rules, for example there is the rule that defines all exclusions:
define exclusions:
...
@ -55,8 +54,7 @@ There are rules that will serve as hooks:
Rule Type: Exclusions
---------------------
Because exclusions are resolved at run time, and only when needed, they should
be stored in a readily-interpreted form:
Because exclusions are resolved at run time, and only when needed, they should be stored in a readily-interpreted form:
define exclusions:
monday = <8:00:00 12:00:00-12:45:00 >17:30:00
@ -69,17 +67,15 @@ be stored in a readily-interpreted form:
2016_01_01 = Working
2016_01_02 = Off
If you want to track your lunch breaks, then you would make a tag for it, and
track it like any other project. If you do not want to track that time, add an
exclusion for it.
If you want to track your lunch breaks, then you would make a tag for it, and track it like any other project.
If you do not want to track that time, add an exclusion for it.
Rule Type: General
------------------
There are rules triggered by changes to the data. In this example, rule 'one'
is a constraint that prevents the value 'foo' from exceeding three. It is
triggered by a change to 'foo', which is a DOM reference, and can prevent the
update by failing:
There are rules triggered by changes to the data.
In this example, rule 'one' is a constraint that prevents the value 'foo' from exceeding three.
It is triggered by a change to 'foo', which is a DOM reference, and can prevent the update by failing:
define rules:
one:
@ -92,8 +88,7 @@ Note that this rule is defined as applying to the tagset 'tag1'.
Rule Type: Tag
--------------
A defined tag is a way to associate metadata with a tag, such as a description
and start/end dates for use:
A defined tag is a way to associate metadata with a tag, such as a description and start/end dates for use:
define tags:
"tag1":
@ -107,8 +102,7 @@ and start/end dates for use:
Rule Type: Theme
----------------
A color theme is defined by a rule, and consists of color definitions for
various report and feedback elements:
A color theme is defined by a rule, and consists of color definitions for various report and feedback elements:
define theme:
description = "A monochrome, 256-color theme"
@ -120,20 +114,16 @@ various report and feedback elements:
color2 = "white on blue"
...
The palette group is a list (more is better) of themed colors for use when auto-
coloring tags.
The palette group is a list (more is better) of themed colors for use when auto-coloring tags.
There is only one theme namespace, so if multiple themes are imported, the last
one can override all the prior theme settings. This means themes can be layered,
but they would need to be designed for this.
There is only one theme namespace, so if multiple themes are imported, the last one can override all the prior theme settings.
This means themes can be layered, but they would need to be designed for this.
Rule Type: Hook
---------------
While there may not be hooks in the traditional sense, with fixed arguments,
there will be rules that have the same role. Hook rules will allow an internal
event to trigger a rule that calls an external script, and passes an arbitrary
set of arguments.
While there may not be hooks in the traditional sense, with fixed arguments, there will be rules that have the same role.
Hook rules will allow an internal event to trigger a rule that calls an external script, and passes an arbitrary set of arguments.
[Mechanism TBD]
@ -149,8 +139,7 @@ set of arguments.
on_modify:
...
These rules can run an external script and provide arguments, based on rules
DOM access:
These rules can run an external script and provide arguments, based on rules DOM access:
define rules:
on_modify:
@ -159,8 +148,7 @@ DOM access:
Rules Type: Hint
----------------
Hints may be defined using the rules system, to augment the built-in hints that
are used by almost every command.
Hints may be defined using the rules system, to augment the built-in hints that are used by almost every command.
define hints:
staff:
@ -172,8 +160,7 @@ are used by almost every command.
--- Raw Notes ---
- Need to distinguish between regular time and over time, with different rates
and limits.
- Need to distinguish between regular time and over time, with different rates and limits.
- Policy support involves things like:
- warn after 40 hrs/wk
@ -181,8 +168,7 @@ are used by almost every command.
- auto-tag intervals that exceed 40 hrs/wk
- auto-tag intervals during exclusion time
- Need to distinguish between rules that will be supported at 1.0.0, and the
long term enhancements.
- Need to distinguish between rules that will be supported at 1.0.0, and the long term enhancements.
- There will need to be several built-in functions, for use by rules:
@ -193,12 +179,10 @@ are used by almost every command.
These are not good examples.
- Need reports to help users doing fixed-rate work - finding the longest task
for example.
- Need reports to help users doing fixed-rate work - finding the longest task for example.
- If an interval has more than one tag with a defined color, and is being
rendered, then use the first tag color. It doesn't really matter which.
- Use display granularity/resolution to see more or less details. This would
combine nicely with a tag hierarchy. (Tomas Babej)
- If an interval has more than one tag with a defined color, and is being rendered, then use the first tag color.
It doesn't really matter which.
- Use display granularity/resolution to see more or less details.
This would combine nicely with a tag hierarchy. (Tomas Babej)