mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
reformat to one sentence per line
This commit is contained in:
parent
ade706a72e
commit
b1ca5d4cf8
17 changed files with 842 additions and 1052 deletions
|
@ -2,18 +2,16 @@
|
||||||
title: Branching Model
|
title: Branching Model
|
||||||
---
|
---
|
||||||
|
|
||||||
Software development typically requires a standardized branching model, to
|
Software development typically requires a standardized branching model, to manage complexity and parallel efforts.
|
||||||
manage complexity and parallel efforts. The branching model can be a source of
|
The branching model can be a source of confusion for developers, so this document describes how branching is used.
|
||||||
confusion for developers, so this document describes how branching is used.
|
|
||||||
|
|
||||||
Taskwarrior and Taskserver use the same branching model.
|
Taskwarrior and Taskserver use the same branching model.
|
||||||
|
|
||||||
|
|
||||||
## Git Branching
|
## Git Branching
|
||||||
|
|
||||||
Git allows arbitrary and low-cost branching, which means that any branching
|
Git allows arbitrary and low-cost branching, which means that any branching model can be used.
|
||||||
model can be used. A new Git repository has one branch, the default branch,
|
A new Git repository has one branch, the default branch, named `master`, but even this is not required.
|
||||||
named `master`, but even this is not required.
|
|
||||||
|
|
||||||
[](/docs/images/master.png)
|
[](/docs/images/master.png)
|
||||||
|
|
||||||
|
@ -22,9 +20,9 @@ No development occurs on the `master` branch.
|
||||||
|
|
||||||
## Development Branch
|
## Development Branch
|
||||||
|
|
||||||
A development branch is created from the `master` branch, and work proceeds on
|
A development branch is created from the `master` branch, and work proceeds on the development branch.
|
||||||
the development branch. Development branches are pushed to the server. Note that
|
Development branches are pushed to the server.
|
||||||
there are no changes on `master` - all work is done on dev branches.
|
Note that there are no changes on `master` - all work is done on dev branches.
|
||||||
|
|
||||||
[](/docs/images/dev.png)
|
[](/docs/images/dev.png)
|
||||||
|
|
||||||
|
@ -33,53 +31,47 @@ All work on dev branches is pushed to the server.
|
||||||
|
|
||||||
## Topic Branch
|
## Topic Branch
|
||||||
|
|
||||||
A topic branch is created from a dev branch. This can be a useful way to manage
|
A topic branch is created from a dev branch.
|
||||||
parallel efforts on a single development machine. Topic branches are also useful
|
This can be a useful way to manage parallel efforts on a single development machine.
|
||||||
for merging in submitted patches, because the patch can be merged, tested and
|
Topic branches are also useful for merging in submitted patches, because the patch can be merged, tested and corrected independently of other efforts before being merged and pushed.
|
||||||
corrected independently of other efforts before being merged and pushed. A topic
|
A topic branch is ideal for storage of changes before an eventual merge back to the development branch.
|
||||||
branch is ideal for storage of changes before an eventual merge back to the
|
|
||||||
development branch.
|
|
||||||
|
|
||||||
[](/docs/images/topic.png)
|
[](/docs/images/topic.png)
|
||||||
|
|
||||||
No topic branches are pushed to the server, they are kept local to the
|
No topic branches are pushed to the server, they are kept local to the development machine.
|
||||||
development machine. They are private, and therefore hidden from the server.
|
They are private, and therefore hidden from the server.
|
||||||
|
|
||||||
|
|
||||||
## Release
|
## Release
|
||||||
|
|
||||||
When a release is made, the development branch is merged back to the `master`
|
When a release is made, the development branch is merged back to the `master` branch, and a tag is applied that indicates which commit represents the release.
|
||||||
branch, and a tag is applied that indicates which commit represents the release.
|
|
||||||
|
|
||||||
[](/docs/images/release.png)
|
[](/docs/images/release.png)
|
||||||
|
|
||||||
Because only releases are merged back, the `master` branch always represent the
|
Because only releases are merged back, the `master` branch always represent the stable release.
|
||||||
stable release.
|
|
||||||
|
|
||||||
|
|
||||||
## New Development Branches
|
## New Development Branches
|
||||||
|
|
||||||
Immediately after a release, one or more new branches are created. Typically
|
Immediately after a release, one or more new branches are created.
|
||||||
after a major \'1.0.0\' release, there will be two branches created. First the
|
Typically after a major \'1.0.0\' release, there will be two branches created.
|
||||||
\'1.0.1\' branch is a patch development branch, intended to be used if an
|
First the \'1.0.1\' branch is a patch development branch, intended to be used if an emergency patch is required.
|
||||||
emergency patch is required. It therefore sits unused until an emergency arises.
|
It therefore sits unused until an emergency arises.
|
||||||
No work is performed on a patch development branch.
|
No work is performed on a patch development branch.
|
||||||
|
|
||||||
The second branch, with the higher release number is the development branch for
|
The second branch, with the higher release number is the development branch for fixes and features.
|
||||||
fixes and features. This is where all the work occurs. Any fix made on the
|
This is where all the work occurs.
|
||||||
development branch can be cherry-picked onto the patch branch, if necessary.
|
Any fix made on the development branch can be cherry-picked onto the patch branch, if necessary.
|
||||||
|
|
||||||
[](/docs/images/dev2.png)
|
[](/docs/images/dev2.png)
|
||||||
|
|
||||||
To address the confusion around branching, namely determining which branch is
|
To address the confusion around branching, namely determining which branch is active.
|
||||||
active. the answer is that the highest numbered branch is the one that patches
|
the answer is that the highest numbered branch is the one that patches should be applied to.
|
||||||
should be applied to.
|
|
||||||
|
|
||||||
|
|
||||||
## Old Branches
|
## Old Branches
|
||||||
|
|
||||||
Old branches are not retained, but there are tags marking the beginning and end
|
Old branches are not retained, but there are tags marking the beginning and end of development on a branch.
|
||||||
of development on a branch.
|
|
||||||
|
|
||||||
|
|
||||||
## Rebasing
|
## Rebasing
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
title: How To Build Taskwarrior
|
title: How To Build Taskwarrior
|
||||||
---
|
---
|
||||||
|
|
||||||
This is for developers. Specifically those who know how to use tools, satisfy
|
This is for developers.
|
||||||
dependencies, and want to set up a development environment. It is not
|
Specifically those who know how to use tools, satisfy dependencies, and want to set up a development environment.
|
||||||
user-friendly.
|
It is not user-friendly.
|
||||||
|
|
||||||
You\'ll need these tools:
|
You\'ll need these tools:
|
||||||
|
|
||||||
|
@ -55,9 +55,8 @@ Build the debug type if you want symbols in the binary.
|
||||||
|
|
||||||
# Running the Test Suite
|
# Running the Test Suite
|
||||||
|
|
||||||
There are scripts to facilitate running the test suite. In particular, the
|
There are scripts to facilitate running the test suite.
|
||||||
[vramsteg](https://gothenburgbitfactory.org/projects/vramsteg) utility
|
In particular, the [vramsteg](https://gothenburgbitfactory.org/projects/vramsteg) utility provides blinkenlights for test progress.
|
||||||
provides blinkenlights for test progress.
|
|
||||||
|
|
||||||
$ cd taskwarrior.git/test
|
$ cd taskwarrior.git/test
|
||||||
$ make VERBOSE=1 # Shows details
|
$ make VERBOSE=1 # Shows details
|
||||||
|
@ -68,9 +67,10 @@ provides blinkenlights for test progress.
|
||||||
# Submitting a Patch
|
# Submitting a Patch
|
||||||
|
|
||||||
Talk to us first - make sure you are working on something that is wanted.
|
Talk to us first - make sure you are working on something that is wanted.
|
||||||
Patches will not be applied simply because you did the work. Remember the
|
Patches will not be applied simply because you did the work.
|
||||||
various forms of documentation involved, and the test suite. Work on the dev
|
Remember the various forms of documentation involved, and the test suite.
|
||||||
branch, not `master`. When you are are ready to submit, do this:
|
Work on the dev branch, not `master`.
|
||||||
|
When you are are ready to submit, do this:
|
||||||
|
|
||||||
$ git commit
|
$ git commit
|
||||||
|
|
||||||
|
@ -94,11 +94,9 @@ Create the patch using this:
|
||||||
|
|
||||||
$ git format-patch HEAD^
|
$ git format-patch HEAD^
|
||||||
|
|
||||||
Mail the patch to <taskwarrior-dev@googlegroups.com> or attach it to the
|
Mail the patch to <taskwarrior-dev@googlegroups.com> or attach it to the appropriate ticket in the [bug tracker](https://github.com/GothenburgBitFactory/taskwarrior/issues).
|
||||||
appropriate ticket in the [bug
|
If you do the latter, make sure someone knows about it, or it could go unnoticed.
|
||||||
tracker](https://github.com/GothenburgBitFactory/taskwarrior/issues). If you do
|
|
||||||
the latter, make sure someone knows about it, or it could go unnoticed.
|
|
||||||
|
|
||||||
Expect feedback. It is unlikely your patch will be accepted unmodified. Usually
|
Expect feedback.
|
||||||
this is because you violated the coding style, worked in the wrong branch, or
|
It is unlikely your patch will be accepted unmodified.
|
||||||
*forgot* about documentation and unit tests.
|
Usually this is because you violated the coding style, worked in the wrong branch, or *forgot* about documentation and unit tests.
|
||||||
|
|
|
@ -2,30 +2,27 @@
|
||||||
title: Coding Style
|
title: Coding Style
|
||||||
---
|
---
|
||||||
|
|
||||||
The coding style used for the Taskwarrior, Taskserver, and other codebases is
|
The coding style used for the Taskwarrior, Taskserver, and other codebases is deliberately kept simple and a little vague.
|
||||||
deliberately kept simple and a little vague. This is because there are many
|
This is because there are many languages involved (C++, C, Python, sh, bash, HTML, troff and more), and specіfying those would be a major effort that detracts from the main focus which is improving the software.
|
||||||
languages involved (C++, C, Python, sh, bash, HTML, troff and more), and
|
|
||||||
specіfying those would be a major effort that detracts from the main focus which
|
|
||||||
is improving the software.
|
|
||||||
|
|
||||||
Instead, the general guideline is simply this:
|
Instead, the general guideline is simply this:
|
||||||
|
|
||||||
Make all changes and additions such that they blend in perfectly with the
|
Make all changes and additions such that they blend in perfectly with the surrounding code, so it looks like only one person worked on the source, and that person is rigidly consistent.
|
||||||
surrounding code, so it looks like only one person worked on the source, and
|
|
||||||
that person is rigidly consistent.
|
|
||||||
|
|
||||||
To be a little more explicit, the common elements across the languages are:
|
To be a little more explicit, the common elements across the languages are:
|
||||||
|
|
||||||
- Indent code using two spaces, no tabs
|
- Indent code using two spaces, no tabs
|
||||||
- With Python, follow [PEP8](https://www.python.org/dev/peps/pep-0008/) as
|
|
||||||
much as possible
|
- With Python, follow [PEP8](https://www.python.org/dev/peps/pep-0008/) as much as possible
|
||||||
|
|
||||||
- Surround operators and expression terms with a space
|
- Surround operators and expression terms with a space
|
||||||
|
|
||||||
- No cuddled braces
|
- No cuddled braces
|
||||||
|
|
||||||
- Class names are capitalized, variable names are not
|
- Class names are capitalized, variable names are not
|
||||||
|
|
||||||
We target Python 2.7 so that our test suite runs on the broadest set of
|
We target Python 2.7 so that our test suite runs on the broadest set of platforms.
|
||||||
platforms. This will likely change in the future and 2.7 will be dropped.
|
This will likely change in the future and 2.7 will be dropped.
|
||||||
|
|
||||||
We can safely target C++11 because all the default compilers on our supported
|
We can safely target C++11 because all the default compilers on our supported platforms are ready.
|
||||||
platforms are ready. Feel free to use C++14 and C++17 provided that all build
|
Feel free to use C++14 and C++17 provided that all build platforms support thi
|
||||||
platforms support this.
|
|
||||||
|
|
|
@ -2,45 +2,62 @@
|
||||||
title: Contributing to Taskwarrior
|
title: Contributing to Taskwarrior
|
||||||
---
|
---
|
||||||
|
|
||||||
Help is needed in all areas of Taskwarrior development - design, coding,
|
Help is needed in all areas of Taskwarrior development - design, coding, testing, support and marketing.
|
||||||
testing, support and marketing. Applicants must be friendly. Perhaps you are
|
Applicants must be friendly.
|
||||||
looking to help, but don\'t know where to start. You can of course [email
|
Perhaps you are looking to help, but don\'t know where to start.
|
||||||
us](mailto:taskwarrior-dev@googlegroups.com) but take a look at this list.
|
You can of course [email us](mailto:taskwarrior-dev@googlegroups.com) but take a look at this list.
|
||||||
Perhaps you have skills we are looking for, here are ways you may be able to
|
Perhaps you have skills we are looking for, here are ways you may be able to help:
|
||||||
help:
|
|
||||||
|
- Use Taskwarrior, become familiar with it, and make suggestions.
|
||||||
|
We get great feedback from both new users and veteran users.
|
||||||
|
New users have a fresh approach that we can no longer achieve, while veteran users develop clever and crafty ways to use the product.
|
||||||
|
|
||||||
|
- Report bugs and odd behavior when you see it.
|
||||||
|
We don\'t necessarily know it\'s broken, unless you tell us.
|
||||||
|
|
||||||
|
- Suggest enhancements.
|
||||||
|
We get lots of these, and it\'s great.
|
||||||
|
Some really good ideas have been suggested and implemented.
|
||||||
|
Sure, some are out of scope, or plain crazy, but the stream of suggestions is fascinating to think about.
|
||||||
|
|
||||||
|
- Participate in the [bug tracking](https://github.com/GothenburgBitFactory/taskwarrior/issues) database, to help others and maybe learn something yourself.
|
||||||
|
|
||||||
- Use Taskwarrior, become familiar with it, and make suggestions. We get great
|
|
||||||
feedback from both new users and veteran users. New users have a fresh
|
|
||||||
approach that we can no longer achieve, while veteran users develop clever
|
|
||||||
and crafty ways to use the product.
|
|
||||||
- Report bugs and odd behavior when you see it. We don\'t necessarily know
|
|
||||||
it\'s broken, unless you tell us.
|
|
||||||
- Suggest enhancements. We get lots of these, and it\'s great. Some really
|
|
||||||
good ideas have been suggested and implemented. Sure, some are out of scope,
|
|
||||||
or plain crazy, but the stream of suggestions is fascinating to think about.
|
|
||||||
- Participate in the [bug
|
|
||||||
tracking](https://github.com/GothenburgBitFactory/taskwarrior/issues)
|
|
||||||
database, to help others and maybe learn something yourself.
|
|
||||||
- Help [triage](/docs/triage) the issues list.
|
- Help [triage](/docs/triage) the issues list.
|
||||||
- Join the IRC channel \#taskwarrior on freenode.net and help answer some
|
|
||||||
questions.
|
- Join the IRC channel \#taskwarrior on freenode.net and help answer some questions.
|
||||||
- Join either the
|
|
||||||
[developer-mailinglist](https://groups.google.com/forum/#!forum/taskwarrior-dev)
|
- Join either the [developer-mailinglist](https://groups.google.com/forum/#!forum/taskwarrior-dev) or [user-mailinglist](https://groups.google.com/forum/#!forum/taskwarrior-user) (or both) and participate.
|
||||||
or
|
|
||||||
[user-mailinglist](https://groups.google.com/forum/#!forum/taskwarrior-user)
|
|
||||||
(or both) and participate.
|
|
||||||
- Proofread the documentation and man pages.
|
- Proofread the documentation and man pages.
|
||||||
|
|
||||||
- Improve the documentation.
|
- Improve the documentation.
|
||||||
|
|
||||||
- Improve the man pages.
|
- Improve the man pages.
|
||||||
- Help improve the tutorials. Make your own tutorial.
|
|
||||||
- Confirm a bug. Nothing gets fixed without confirmation.
|
- Help improve the tutorials.
|
||||||
- Refine a bug. Provide relevant details, elaborate on the behavior.
|
Make your own tutorial.
|
||||||
- Fix a bug. Send a patch. You\'ll need C++ skills for this.
|
|
||||||
- Write a unit test. Improve an existing unit test.
|
- Confirm a bug.
|
||||||
- Spread the word. Help others become more effective at managing tasks. Share
|
Nothing gets fixed without confirmation.
|
||||||
your methodology, to inspire others.
|
|
||||||
- Encouragement. Tell us what works for you, and what doesn\'t. It\'s all
|
- Refine a bug.
|
||||||
good.
|
Provide relevant details, elaborate on the behavior.
|
||||||
|
|
||||||
|
- Fix a bug.
|
||||||
|
Send a patch.
|
||||||
|
You\'ll need C++ skills for this.
|
||||||
|
|
||||||
|
- Write a unit test.
|
||||||
|
Improve an existing unit test.
|
||||||
|
|
||||||
|
- Spread the word.
|
||||||
|
Help others become more effective at managing tasks.
|
||||||
|
Share your methodology, to inspire others.
|
||||||
|
|
||||||
|
- Encouragement.
|
||||||
|
Tell us what works for you, and what doesn\'t.
|
||||||
|
It\'s all good.
|
||||||
|
|
||||||
- Donate! Help offset costs.
|
- Donate! Help offset costs.
|
||||||
|
|
||||||
Please remember that we need contributions from all skillsets, however small.
|
Please remember that we need contributions from all skillsets, however small.
|
||||||
|
|
|
@ -28,121 +28,123 @@ title: How to Build Taskwarrior
|
||||||
$ ./problems # Enumerate test failures in all.log
|
$ ./problems # Enumerate test failures in all.log
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that any development should be performed using a git clone, and the
|
Note that any development should be performed using a git clone, and the current development branch.
|
||||||
current development branch. The source tarballs do not reflect HEAD, and do
|
The source tarballs do not reflect HEAD, and do not contain the test suite.
|
||||||
not contain the test suite.
|
|
||||||
|
|
||||||
If you send a patch (support@gothenburgbitfactory.org), make sure that patch is made
|
If you send a patch (support@gothenburgbitfactory.org), make sure that patch is made against git HEAD on the development branch.
|
||||||
against git HEAD on the development branch. We cannot apply patches made
|
We cannot apply patches made against the tarball source, or master.
|
||||||
against the tarball source, or master.
|
|
||||||
|
|
||||||
|
|
||||||
# General Statement
|
# General Statement
|
||||||
This file is intended to convey the current efforts, priorities and needs of
|
|
||||||
the code base. It is for anyone looking for a way to start contributing.
|
This file is intended to convey the current efforts, priorities and needs of the code base.
|
||||||
|
It is for anyone looking for a way to start contributing.
|
||||||
Here are many ways to contribute that may not be obvious:
|
Here are many ways to contribute that may not be obvious:
|
||||||
|
|
||||||
* Use Taskwarrior, become familiar with it, and make suggestions. There are
|
* Use Taskwarrior, become familiar with it, and make suggestions.
|
||||||
always ongoing discussions about new features and changes to existing
|
There are always ongoing discussions about new features and changes to existing features.
|
||||||
features.
|
|
||||||
|
|
||||||
* Join us in the #taskwarrior IRC channel on freenode.net or libera.chat.
|
* Join us in the #taskwarrior IRC channel on freenode.net or libera.chat.
|
||||||
Many great ideas, suggestions, testing and discussions have taken place
|
Many great ideas, suggestions, testing and discussions have taken place there.
|
||||||
there. It is also the quickest way to get help, or confirm a bug.
|
It is also the quickest way to get help, or confirm a bug.
|
||||||
|
|
||||||
* Review documentation: there are man pages, online articles, tutorials and
|
* 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.
|
||||||
so on, and these may contain errors, or they may not convey ideas in the
|
Perhaps you can help improve it.
|
||||||
best way. Perhaps you can help improve it. Contact us - documentation is
|
Contact us - documentation is a separate effort from the code base, and includes all web sites, and all are available as git repositories.
|
||||||
a separate effort from the code base, and includes all web sites, and all
|
|
||||||
are available as git repositories.
|
|
||||||
|
|
||||||
* Take a look at the bug database, and help triage the bug list. This is a
|
* Take a look at the bug database, and help triage the bug list.
|
||||||
review process that involves confirming bugs, providing additional data,
|
This is a review process that involves confirming bugs, providing additional data, information or analysis.
|
||||||
information or analysis. Bug triage is very useful and much needed. You
|
Bug triage is very useful and much needed.
|
||||||
could check to see that an old bug is still relevant - sometimes they are
|
You could check to see that an old bug is still relevant - sometimes they are not.
|
||||||
not.
|
|
||||||
|
|
||||||
* Review the source code, and point out inefficiencies, problems, unreadable
|
* Review the source code, and point out inefficiencies, problems, unreadable functions, bugs and assumptions.
|
||||||
functions, bugs and assumptions.
|
|
||||||
|
|
||||||
* Fix a bug. For this you'll need C++ and Git skills. We welcome all bug
|
* Fix a bug.
|
||||||
fixes, provided the work is done well and doesn't create other problems or
|
For this you'll need C++ and Git skills.
|
||||||
introduce new dependencies. We recommend talking to us before starting.
|
We welcome all bug fixes, provided the work is done well and doesn't create other problems or introduce new dependencies.
|
||||||
|
We recommend talking to us before starting.
|
||||||
Seriously.
|
Seriously.
|
||||||
|
|
||||||
* Add unit tests. Unit tests are possibly the most useful contributions of
|
* Add unit tests.
|
||||||
all, because they not only improve the quality of the code, but prevent
|
Unit tests are possibly the most useful contributions of all, because they not only improve the quality of the code, but prevent future regressions, therefore maintaining quality of subsequent releases.
|
||||||
future regressions, therefore maintaining quality of subsequent releases.
|
|
||||||
Plus, broken tests are a great motivator for us to fix the causal defect.
|
Plus, broken tests are a great motivator for us to fix the causal defect.
|
||||||
You'll need Python skills.
|
You'll need Python skills.
|
||||||
|
|
||||||
* Add a feature. Well, let's be very clear about this: adding a feature is
|
* Add a feature.
|
||||||
not usually well-received, and if you add a feature and send a patch, it
|
Well, let's be very clear about this: adding a feature is not usually well-received, and if you add a feature and send a patch, it will most likely be rejected.
|
||||||
will most likely be rejected. The reason for this is that there are many
|
The reason for this is that there are many efforts under way, in various code branches.
|
||||||
efforts under way, in various code branches. There is a very good chance
|
There is a very good chance that the feature you add is either already in progress, or being done in a way that is more fitting when considering other work in progress.
|
||||||
that the feature you add is either already in progress, or being done in a
|
So if you want to add a feature, please don't.
|
||||||
way that is more fitting when considering other work in progress. So if
|
Start by talking to us, and find out what is currently under way or planned.
|
||||||
you want to add a feature, please don't. Start by talking to us, and find
|
You might find that we've already rejected such a feature for some very good reasons.
|
||||||
out what is currently under way or planned. You might find that we've
|
So please check first, so we don't duplicate effort or waste anyone's time.
|
||||||
already rejected such a feature for some very good reasons. So please
|
|
||||||
check first, so we don't duplicate effort or waste anyone's time.
|
|
||||||
|
|
||||||
* Spread the word. Help others become more effective at managing tasks.
|
* Spread the word.
|
||||||
|
Help others become more effective at managing tasks.
|
||||||
|
|
||||||
* Encouragement. Tell us what works for you, and what doesn't. Tell us about
|
* Encouragement.
|
||||||
your methodology for managing tasks. It's all useful information.
|
Tell us what works for you, and what doesn't.
|
||||||
|
Tell us about your methodology for managing tasks.
|
||||||
|
It's all useful information.
|
||||||
|
|
||||||
* Request a feature. This not only tells us that you think something is
|
* Request a feature.
|
||||||
missing from the software, but gives us insights into how you use it.
|
This not only tells us that you think something is missing from the software, but gives us insights into how you use it.
|
||||||
Plus, you might get your feature implemented.
|
Plus, you might get your feature implemented.
|
||||||
|
|
||||||
# Unit Tests Needed
|
# Unit Tests Needed
|
||||||
There are always more unit tests needed. More specifically, better unit tests
|
|
||||||
are always needed. The convention is that there are four types of unit test:
|
There are always more unit tests needed.
|
||||||
|
More specifically, better unit tests are always needed.
|
||||||
|
The convention is that there are four types of unit test:
|
||||||
|
|
||||||
1. High level tests that exercise large features, or combinations of commands.
|
1. High level tests that exercise large features, or combinations of commands.
|
||||||
For example, dependencies.t runs through a long list of commands that test
|
For example, dependencies.t runs through a long list of commands that test dependencies, but do so by using 'add', 'modify', 'done' and 'delete'.
|
||||||
dependencies, but do so by using 'add', 'modify', 'done' and 'delete'.
|
|
||||||
1. Regression tests that ensure certain bugs are fixed and stay fixed. These
|
2. Regression tests that ensure certain bugs are fixed and stay fixed.
|
||||||
tests are named tw-NNNN.t where NNNN refers to the bug number. While it is
|
These tests are named tw-NNNN.t where NNNN refers to the bug number.
|
||||||
not worth creating tests for small fixes like typos, it is for logic
|
While it is not worth creating tests for small fixes like typos, it is for logic changes.
|
||||||
changes.
|
|
||||||
1. Small feature tests. When small features are added, we would like small,
|
3. Small feature tests.
|
||||||
low-level feature tests named feature.t, with a descriptive name and
|
When small features are added, we would like small, low-level feature tests named feature.t, with a descriptive name and focused tests.
|
||||||
focused tests.
|
|
||||||
1. Code tests. These are tests written in C++ that exercise C++ objects, or
|
4. Code tests.
|
||||||
function calls. These are the lowest level tests. It is important that
|
These are tests written in C++ that exercise C++ objects, or function calls.
|
||||||
these kind of tests be extensive and thorough, because the software depends
|
These are the lowest level tests.
|
||||||
on this code the most.
|
It is important that these kind of tests be extensive and thorough, because the software depends on this code the most.
|
||||||
|
|
||||||
The tests are written in Python, Bash and C++, and all use TAP.
|
The tests are written in Python, Bash and C++, and all use TAP.
|
||||||
|
|
||||||
## Tests needed
|
## Tests needed
|
||||||
|
|
||||||
* Take a look at the bug database (https://github.com/GothenburgBitFactory/taskwarrior/issues)
|
* Take a look at the bug database (https://github.com/GothenburgBitFactory/taskwarrior/issues) and notice that many issues, open and closed, have the "needsTest" label.
|
||||||
and notice that many issues, open and closed, have the "needsTest" label.
|
These are things that we would like to see in the test suite, as regression tests.
|
||||||
These are things that we would like to see in the test suite, as regression
|
|
||||||
tests.
|
|
||||||
|
|
||||||
All new unit tests should follow the test/template.t standard.
|
All new unit tests should follow the test/template.t standard.
|
||||||
|
|
||||||
# Patches
|
# Patches
|
||||||
Patches are encouraged and welcomed. Either send a pull request on Github or
|
|
||||||
email a patch to support@taskwarrior.org. A good patch:
|
|
||||||
|
|
||||||
* Maintains the MIT license, and does not contain code lifted from other
|
Patches are encouraged and welcomed.
|
||||||
sources. You will have written 100% of the code in the patch, otherwise
|
Either send a pull request on Github or email a patch to support@taskwarrior.org.
|
||||||
we cannot maintain the license.
|
A good patch:
|
||||||
|
|
||||||
|
* Maintains the MIT license, and does not contain code lifted from other sources.
|
||||||
|
You will have written 100% of the code in the patch, otherwise we cannot maintain the license.
|
||||||
|
|
||||||
* Precisely addresses one issue only.
|
* Precisely addresses one issue only.
|
||||||
* Doesn't break unit tests. This means yes, run the unit tests.
|
|
||||||
|
* Doesn't break unit tests.
|
||||||
|
This means yes, run the unit tests.
|
||||||
|
|
||||||
* Doesn't introduce dependencies.
|
* Doesn't introduce dependencies.
|
||||||
|
|
||||||
* Is accompanied by new or updated unit tests, where appropriate.
|
* Is accompanied by new or updated unit tests, where appropriate.
|
||||||
|
|
||||||
* Is accompanied by documentation changes, where appropriate.
|
* Is accompanied by documentation changes, where appropriate.
|
||||||
* Conforms to the prevailing coding standards - in other words, it should
|
|
||||||
fit in with the existing code.
|
* Conforms to the prevailing coding standards - in other words, it should fit in with the existing code.
|
||||||
|
|
||||||
A patch may be rejected for violating any of the above rules, and more.
|
A patch may be rejected for violating any of the above rules, and more.
|
||||||
Bad patches may be accepted and modified depending on work load and mood. It
|
Bad patches may be accepted and modified depending on work load and mood.
|
||||||
is possible that a patch may be rejected because it conflicts in some way with
|
It is possible that a patch may be rejected because it conflicts in some way with plans or upcoming changes.
|
||||||
plans or upcoming changes. Check with us first, before sinking time and effort
|
Check with us first, before sinking time and effort into a patch.
|
||||||
into a patch.
|
|
||||||
|
|
|
@ -2,48 +2,38 @@
|
||||||
title: How to become an Open Source Contributor
|
title: How to become an Open Source Contributor
|
||||||
---
|
---
|
||||||
|
|
||||||
Welcome, potential new Open Source contributor! This is a guide to show you
|
Welcome, potential new Open Source contributor! This is a guide to show you exactly how to make a contribution, and will lead you through the entire process.
|
||||||
exactly how to make a contribution, and will lead you through the entire
|
|
||||||
process.
|
|
||||||
|
|
||||||
There are many people who wish to start contributing, but don\'t know how or
|
There are many people who wish to start contributing, but don\'t know how or where to start.
|
||||||
where to start. If this might be the case, then please read on, this guide is
|
If this might be the case, then please read on, this guide is for you.
|
||||||
for you. Because we want you to join in the fun with Open Source - it can be fun
|
Because we want you to join in the fun with Open Source - it can be fun and rewarding, improve your skills, or just give you a way to contribute back to a project.
|
||||||
and rewarding, improve your skills, or just give you a way to contribute back to
|
|
||||||
a project.
|
|
||||||
|
|
||||||
Where else can you combine the thrill of typing in a darkened room with the
|
Where else can you combine the thrill of typing in a darkened room with the kindhearted love of an internet forum? Just kidding!
|
||||||
kindhearted love of an internet forum? Just kidding!
|
|
||||||
|
|
||||||
The goal of this document is to give you the ability to make your first
|
The goal of this document is to give you the ability to make your first contribution, and encourage you to make a second, by showing you how simple it is.
|
||||||
contribution, and encourage you to make a second, by showing you how simple it
|
Perhaps confidence and a little familiarity with the process are all you need to get started.
|
||||||
is. Perhaps confidence and a little familiarity with the process are all you
|
|
||||||
need to get started.
|
|
||||||
|
|
||||||
We\'re going to pick the smallest contribution of all - a typo fix. While this
|
We\'re going to pick the smallest contribution of all - a typo fix.
|
||||||
may be a very small improvement, it is nevertheless a wanted improvement, and
|
While this may be a very small improvement, it is nevertheless a wanted improvement, and will be welcomed.
|
||||||
will be welcomed. Fixes such as this happen many times a day. Similar work on
|
Fixes such as this happen many times a day.
|
||||||
new features, new documents, rewriting help, refactoring code, fixing bugs and
|
Similar work on new features, new documents, rewriting help, refactoring code, fixing bugs and improving performance all combine to make a project grow and improve.
|
||||||
improving performance all combine to make a project grow and improve.
|
|
||||||
|
|
||||||
Making a bigger change also is certainly an option, but the focus here is on
|
Making a bigger change also is certainly an option, but the focus here is on going through the procedure, which is somewhat independent from the nature of the change.
|
||||||
going through the procedure, which is somewhat independent from the nature of
|
The steps are numbered, and it all fits on this one page.
|
||||||
the change. The steps are numbered, and it all fits on this one page. Get all
|
Get all the way to the end, and you will be an open source contributor.
|
||||||
the way to the end, and you will be an open source contributor.
|
|
||||||
|
|
||||||
|
|
||||||
## [1] Development Environment Setup
|
## [1] Development Environment Setup
|
||||||
|
|
||||||
In order to build and test software, you need a development environment. That\'s
|
In order to build and test software, you need a development environment.
|
||||||
just a term that means you need certain tools installed before proceeding. Here
|
That\'s just a term that means you need certain tools installed before proceeding.
|
||||||
are the tools that Taskwarrior needs:
|
Here are the tools that Taskwarrior needs:
|
||||||
|
|
||||||
- Compiler: GCC 4.7 or newer, or Clang 3.4 or newer.
|
- Compiler: GCC 4.7 or newer, or Clang 3.4 or newer.
|
||||||
- Libraries: GnuTLS, and libuuid
|
- Libraries: GnuTLS, and libuuid
|
||||||
- Tools: Git, CMake, make, Python
|
- Tools: Git, CMake, make, Python
|
||||||
|
|
||||||
The procedure for installing this software is OS-dependent, but here are the
|
The procedure for installing this software is OS-dependent, but here are the commands you would use on Debian:
|
||||||
commands you would use on Debian:
|
|
||||||
|
|
||||||
$ sudo apt-get install gcc
|
$ sudo apt-get install gcc
|
||||||
$ sudo apt-get install libgnutls28-dev
|
$ sudo apt-get install libgnutls28-dev
|
||||||
|
@ -55,8 +45,8 @@ commands you would use on Debian:
|
||||||
|
|
||||||
## [2] Get the Code
|
## [2] Get the Code
|
||||||
|
|
||||||
Now you have the tools, next you need the code. This involves cloning the
|
Now you have the tools, next you need the code.
|
||||||
repository using git and looking at the development branch:
|
This involves cloning the repository using git and looking at the development branch:
|
||||||
|
|
||||||
$ git clone --recursive -b 2.6.0 https://github.com/GothenburgBitFactory/taskwarrior.git taskwarrior.git
|
$ git clone --recursive -b 2.6.0 https://github.com/GothenburgBitFactory/taskwarrior.git taskwarrior.git
|
||||||
Cloning into 'taskwarrior.git'...
|
Cloning into 'taskwarrior.git'...
|
||||||
|
@ -68,12 +58,10 @@ repository using git and looking at the development branch:
|
||||||
Checking connectivity... done.
|
Checking connectivity... done.
|
||||||
$
|
$
|
||||||
|
|
||||||
The URL for the repository was obtained from looking around on
|
The URL for the repository was obtained from looking around on <https://github.com/GothenburgBitFactory> where several repositories are public, including the one for this web site.
|
||||||
<https://github.com/GothenburgBitFactory> where several repositories are public,
|
|
||||||
including the one for this web site.
|
|
||||||
|
|
||||||
The clone command above puts you on the right branch, so no need to switch. But
|
The clone command above puts you on the right branch, so no need to switch.
|
||||||
it\'s a good idea to check anyway, so do this:
|
But it\'s a good idea to check anyway, so do this:
|
||||||
|
|
||||||
$ cd taskwarrior.git
|
$ cd taskwarrior.git
|
||||||
$ git branch -a
|
$ git branch -a
|
||||||
|
@ -83,46 +71,41 @@ it\'s a good idea to check anyway, so do this:
|
||||||
remotes/origin/master
|
remotes/origin/master
|
||||||
$
|
$
|
||||||
|
|
||||||
Here we see that 2.6.0 is the highest-numbered branch, and therefore the current
|
Here we see that 2.6.0 is the highest-numbered branch, and therefore the current development branch.
|
||||||
development branch. If there were a higher numbered branch, you would want to
|
If there were a higher numbered branch, you would want to use that by doing this:
|
||||||
use that by doing this:
|
|
||||||
|
|
||||||
$ git checkout 2.7.0
|
$ git checkout 2.7.0
|
||||||
|
|
||||||
Here\'s a thought - if this page does not show the latest branch names, then,
|
Here\'s a thought - if this page does not show the latest branch names, then, you know, you could fix that\...
|
||||||
you know, you could fix that\...
|
|
||||||
|
|
||||||
|
|
||||||
## [3] Fix Something
|
## [3] Fix Something
|
||||||
|
|
||||||
Now that you have the code, find something to fix. This may be the hardest step,
|
Now that you have the code, find something to fix.
|
||||||
but knowing how many typos there are in the source code and docs, it shouldn\'t
|
This may be the hardest step, but knowing how many typos there are in the source code and docs, it shouldn\'t take long to find one.
|
||||||
take long to find one. Try looking in the files in these directories:
|
Try looking in the files in these directories:
|
||||||
|
|
||||||
- `taskwarrior.git/doc/man`
|
- `taskwarrior.git/doc/man`
|
||||||
- `taskwarrior.git/scripts`
|
- `taskwarrior.git/scripts`
|
||||||
- `taskwarrior.git/src`
|
- `taskwarrior.git/src`
|
||||||
- `taskwarrior.git/test`
|
- `taskwarrior.git/test`
|
||||||
|
|
||||||
It also doesn\'t need to be a typo, it can instead be a poorly-worded sentence,
|
It also doesn\'t need to be a typo, it can instead be a poorly-worded sentence, or one that could be more clear.
|
||||||
or one that could be more clear. You\'ll find something, whether it is jargon,
|
You\'ll find something, whether it is jargon, mixed tenses, mistakes, or just plain wrong.
|
||||||
mixed tenses, mistakes, or just plain wrong.
|
|
||||||
|
|
||||||
Then fix it, using a text editor. Try to make the smallest possible change to
|
Then fix it, using a text editor.
|
||||||
achieve what you want, because smaller changeѕ are easier to verify and approve,
|
Try to make the smallest possible change to achieve what you want, because smaller changeѕ are easier to verify and approve, and no reviewer wants to receive a large change to approve.
|
||||||
and no reviewer wants to receive a large change to approve.
|
|
||||||
|
|
||||||
|
|
||||||
## [4] Run the Test Suite
|
## [4] Run the Test Suite
|
||||||
|
|
||||||
Taskwarrior has an extensive test suite to prove that things are still working
|
Taskwarrior has an extensive test suite to prove that things are still working as expected.
|
||||||
as expected. You\'ll need to build the program and run this test suite in order
|
You\'ll need to build the program and run this test suite in order to prove to yourself that your fix is good.
|
||||||
to prove to yourself that your fix is good. It may seem like building the
|
It may seem like building the program is overkill, if you only make a small change, but no, it is not.
|
||||||
program is overkill, if you only make a small change, but no, it is not. The
|
The test suite is there to save you from submitting a bad change, and to save Taskwarrior from any mistakes you make.
|
||||||
test suite is there to save you from submitting a bad change, and to save
|
|
||||||
Taskwarrior from any mistakes you make.
|
|
||||||
|
|
||||||
First you have to build the program. Do this:
|
First you have to build the program.
|
||||||
|
Do this:
|
||||||
|
|
||||||
$ cd taskwarrior.git
|
$ cd taskwarrior.git
|
||||||
$ cmake .
|
$ cmake .
|
||||||
|
@ -159,7 +142,8 @@ If the above commands worked, there will be a binary, which you can find:
|
||||||
$ ls -l src/task
|
$ ls -l src/task
|
||||||
-rwxr-xr-x 1 user group Mar 25 18:43 src/task
|
-rwxr-xr-x 1 user group Mar 25 18:43 src/task
|
||||||
|
|
||||||
The next step is to build the test suite. Do this:
|
The next step is to build the test suite.
|
||||||
|
Do this:
|
||||||
|
|
||||||
$ cd test
|
$ cd test
|
||||||
$ make
|
$ make
|
||||||
|
@ -176,8 +160,7 @@ The next step is to build the test suite. Do this:
|
||||||
[100%] Linking CXX executable view.t
|
[100%] Linking CXX executable view.t
|
||||||
[100%] Built target view.t
|
[100%] Built target view.t
|
||||||
|
|
||||||
Now run the test suite, which can take anywhere from 10 - 500 seconds, depending
|
Now run the test suite, which can take anywhere from 10 - 500 seconds, depending on your hardware and OS:
|
||||||
on your hardware and OS:
|
|
||||||
|
|
||||||
$ ./run_all
|
$ ./run_all
|
||||||
Passed: 8300
|
Passed: 8300
|
||||||
|
@ -187,14 +170,16 @@ on your hardware and OS:
|
||||||
Expected failures: 5
|
Expected failures: 5
|
||||||
Runtime: 32.50 seconds
|
Runtime: 32.50 seconds
|
||||||
|
|
||||||
We are looking for zero failed tests, as shown. This means all is well.
|
We are looking for zero failed tests, as shown.
|
||||||
|
This means all is well.
|
||||||
|
|
||||||
|
|
||||||
## [5] Commit the Change
|
## [5] Commit the Change
|
||||||
|
|
||||||
Now you\'ve made a change, built and tested the code. The next step is to commit
|
Now you\'ve made a change, built and tested the code.
|
||||||
the change locally. This example assumes you fixed a typo in the man page. Check
|
The next step is to commit the change locally.
|
||||||
to see which file you changed, stage that file, then commit it:
|
This example assumes you fixed a typo in the man page.
|
||||||
|
Check to see which file you changed, stage that file, then commit it:
|
||||||
|
|
||||||
$ cd taskwarrior.git
|
$ cd taskwarrior.git
|
||||||
$ git status
|
$ git status
|
||||||
|
@ -213,8 +198,7 @@ to see which file you changed, stage that file, then commit it:
|
||||||
1 file changed, 1 insertion(+)
|
1 file changed, 1 insertion(+)
|
||||||
$
|
$
|
||||||
|
|
||||||
Notice how the commit message looks like this: `Category: Brief description`,
|
Notice how the commit message looks like this: `Category: Brief description`, which is how the commit messages should look.
|
||||||
which is how the commit messages should look.
|
|
||||||
|
|
||||||
|
|
||||||
## [6] Make a Patch
|
## [6] Make a Patch
|
||||||
|
@ -228,17 +212,14 @@ Once the commit is made, making a patch is simple:
|
||||||
|
|
||||||
## [7] Submit the Patch
|
## [7] Submit the Patch
|
||||||
|
|
||||||
Finally you just need to email that patch file to
|
Finally you just need to email that patch file to `taskwarrior-dev@googlegroups.com`.
|
||||||
`taskwarrior-dev@googlegroups.com`. You will need to attach it to an email, and
|
You will need to attach it to an email, and not just paste it in, because the mail client will probably mess with the contents, wrapping lines etc, which can make it unusable.
|
||||||
not just paste it in, because the mail client will probably mess with the
|
|
||||||
contents, wrapping lines etc, which can make it unusable.
|
|
||||||
|
|
||||||
What happens next is that a developer will take your patch and study it, to
|
What happens next is that a developer will take your patch and study it, to ascertain whether it really does fix something that is broken.
|
||||||
ascertain whether it really does fix something that is broken. If there is a
|
If there is a problem, you\'ll hear back with some gentle, constructive criticism.
|
||||||
problem, you\'ll hear back with some gentle, constructive criticism. If the
|
If the problem is small, it might just get fixed.
|
||||||
problem is small, it might just get fixed. Then your patch is applied, tested,
|
Then your patch is applied, tested, and if all looks well, pushed to the public repository, and included in the the next release.
|
||||||
and if all looks well, pushed to the public repository, and included in the the
|
Your name will go into the AUTHORS file, and you will be thanked.
|
||||||
next release. Your name will go into the AUTHORS file, and you will be thanked.
|
|
||||||
|
|
||||||
Congratulations! Welcome to the wonderful world of open source involvement. Now
|
Congratulations! Welcome to the wonderful world of open source involvement.
|
||||||
do it again\...
|
Now do it again\...
|
||||||
|
|
140
docs/rfcs/cli.md
140
docs/rfcs/cli.md
|
@ -4,99 +4,95 @@ title: "Taskwarrior - Command Line Interface"
|
||||||
|
|
||||||
## Work in Progress
|
## Work in Progress
|
||||||
|
|
||||||
This design document is a work in progress, and subject to change. Once
|
This design document is a work in progress, and subject to change. Once finalized, the feature will be scheduled for an upcoming release.
|
||||||
finalized, the feature will be scheduled for an upcoming release.
|
|
||||||
|
|
||||||
|
|
||||||
# CLI Syntax Update
|
# CLI Syntax Update
|
||||||
|
|
||||||
The Taskwarrior command line syntax is being updated to allow more consistent
|
The Taskwarrior command line syntax is being updated to allow more consistent and predictable results, while making room for new features.
|
||||||
and predictable results, while making room for new features.
|
|
||||||
|
|
||||||
Adding support for arbitrary expressions on the command line has become
|
Adding support for arbitrary expressions on the command line has become complicated because of the relaxed syntax of Taskwarrior. While the relaxed syntax allows for a very expressive command line, it also creates ambiguity for the parser, which needs to be reduced.
|
||||||
complicated because of the relaxed syntax of Taskwarrior. While the relaxed
|
|
||||||
syntax allows for a very expressive command line, it also creates ambiguity for
|
|
||||||
the parser, which needs to be reduced.
|
|
||||||
|
|
||||||
With some limited and careful changes it will be possible to have a clear and
|
With some limited and careful changes it will be possible to have a clear and unambiguous command line syntax, which means a predictable and deterministic experience.
|
||||||
unambiguous command line syntax, which means a predictable and deterministic
|
|
||||||
experience.
|
|
||||||
|
|
||||||
It should be stated that for straightforward and even current usage patterns,
|
It should be stated that for straightforward and even current usage patterns, the command line will likely not change for you. Another goal is to not require changes to 3rd-party software, where possible. Only the more advanced and as-yet unintroduced features will require a more strict syntax. This is why now is an ideal time to tighten the requirements.
|
||||||
the command line will likely not change for you. Another goal is to not require
|
|
||||||
changes to 3rd-party software, where possible. Only the more advanced and as-yet
|
|
||||||
unintroduced features will require a more strict syntax. This is why now is an
|
|
||||||
ideal time to tighten the requirements.
|
|
||||||
|
|
||||||
|
|
||||||
## Argument Types
|
## Argument Types
|
||||||
|
|
||||||
The argument types supported remain the same, adding some new constructs.
|
The argument types supported remain the same, adding some new constructs.
|
||||||
|
|
||||||
--------------------------------------- ---------------------------------------
|
* Config file override
|
||||||
Config file override `rc:<file>`
|
* `rc:<file>`
|
||||||
|
|
||||||
Configuration override `rc:<name>:<value>` Literal value\
|
* Configuration override
|
||||||
`rc:<name>=<value>` Literal value\
|
* `rc:<name>:<value>` Literal value
|
||||||
`rc:<name>:=<value>` Calculated value
|
* `rc:<name>=<value>` Literal value
|
||||||
|
* `rc:<name>:=<value>` Calculated value
|
||||||
|
|
||||||
Tag `+<tag>`\
|
* Tag
|
||||||
`-<tag>`\
|
* `+<tag>`
|
||||||
`'+tag one'` Multi-word tag
|
* `-<tag>`
|
||||||
|
* `'+tag one'` Multi-word tag
|
||||||
|
|
||||||
Attribute modifier `rc:<name>.<modifier>:<value>`\
|
* Attribute modifier
|
||||||
Modifier is one of:\
|
* `rc:<name>.<modifier>:<value>`
|
||||||
`before`\
|
* Modifier is one of:
|
||||||
`after`\
|
* `before`
|
||||||
`under`\
|
* `after`
|
||||||
`over`\
|
* `under`
|
||||||
`above`\
|
* `over`
|
||||||
`below`\
|
* `above`
|
||||||
`none`\
|
* `below`
|
||||||
`any`\
|
* `none`
|
||||||
`is`\
|
* `any`
|
||||||
`isnt`\
|
* `is`
|
||||||
`equals`\
|
* `isnt`
|
||||||
`not`\
|
* `equals`
|
||||||
`contains`\
|
* `not`
|
||||||
`has`\
|
* `contains`
|
||||||
`hasnt`\
|
* `has`
|
||||||
`left`\
|
* `hasnt`
|
||||||
`right`\
|
* `left`
|
||||||
`startswith`\
|
* `right`
|
||||||
`endswith`\
|
* `startswith`
|
||||||
`word`\
|
* `endswith`
|
||||||
`noword`
|
* `word`
|
||||||
|
* `noword`
|
||||||
|
|
||||||
Search pattern `/<pattern>/`
|
* Search pattern
|
||||||
|
* `/<pattern>/`
|
||||||
|
|
||||||
Substitution `/<from>/<to>/`\
|
* Substitution
|
||||||
`/<from>/<to>/g`
|
* `/<from>/<to>/`
|
||||||
|
* `/<from>/<to>/g`
|
||||||
|
|
||||||
Command `add`\
|
* Command
|
||||||
`done`\
|
* `add`
|
||||||
`delete`\
|
* `done`
|
||||||
`list`\
|
* `delete`
|
||||||
etc.
|
* `list`
|
||||||
|
* etc.
|
||||||
|
|
||||||
Separator `--`
|
* Separator
|
||||||
|
* `--`
|
||||||
|
|
||||||
ID Ranges `<id>[-<id>][,<id>[-<id>]...]`
|
* ID Ranges
|
||||||
|
* `<id>[-<id>][,<id>[-<id>]...]`
|
||||||
|
|
||||||
UUID `<uuid>`
|
* UUID
|
||||||
|
* `<uuid>`
|
||||||
|
|
||||||
Everything Else `<word>`\
|
* Everything Else
|
||||||
`'<word> <word> ...'`
|
* `<word>`
|
||||||
--------------------------------------- ---------------------------------------
|
* `'<word> <word> ...'`
|
||||||
|
|
||||||
|
|
||||||
## New Command Line Rules
|
## New Command Line Rules
|
||||||
|
|
||||||
Certain command line constructs will no longer be supported, and this is imposed
|
Certain command line constructs will no longer be supported, and this is imposed by the new rules:
|
||||||
by the new rules:
|
|
||||||
|
|
||||||
1. Each command line argument may contain only one instance of one argument
|
1. Each command line argument may contain only one instance of one argument type, unless that type is `<word>`.
|
||||||
type, unless that type is `<word>`.
|
|
||||||
|
|
||||||
task add project:Home +tag Repair the thing # Good
|
task add project:Home +tag Repair the thing # Good
|
||||||
task add project:Home +tag 'Repair the thing' # Good
|
task add project:Home +tag 'Repair the thing' # Good
|
||||||
|
@ -118,15 +114,13 @@ by the new rules:
|
||||||
task /one two/ list # Bad
|
task /one two/ list # Bad
|
||||||
task /'one two'/ list # Bad, unless ' is part of the pattern
|
task /'one two'/ list # Bad, unless ' is part of the pattern
|
||||||
|
|
||||||
3. By default, *no* calculations are made, unless the `:=` eval operator is
|
3. By default, *no* calculations are made, unless the `:=` eval operator is used, and if so, the whole argument may need to be quoted or escaped to satisfy Rule 1.
|
||||||
used, and if so, the whole argument may need to be quoted or escaped to
|
|
||||||
satisfy Rule 1.
|
|
||||||
|
|
||||||
task add project:3.project+x # Literal
|
task add project:3.project+x # Literal
|
||||||
task add project:=3.project+x # DOM reference + concatenation
|
task add project:=3.project+x # DOM reference + concatenation
|
||||||
|
|
||||||
4. Bare word search terms are no longer supported. Use the pattern type
|
4. Bare word search terms are no longer supported.
|
||||||
argument instead.
|
Use the pattern type argument instead.
|
||||||
|
|
||||||
task /foo/ list # Good
|
task /foo/ list # Good
|
||||||
task foo list # Bad
|
task foo list # Bad
|
||||||
|
@ -143,8 +137,7 @@ Aside from the command line parser, there are other changes needed:
|
||||||
|
|
||||||
- Many online documents will need to be modified.
|
- Many online documents will need to be modified.
|
||||||
|
|
||||||
- Filters will be automatically parenthesized, so that every command line will
|
- Filters will be automatically parenthesized, so that every command line will now looke like:
|
||||||
now looke like:
|
|
||||||
|
|
||||||
task [overrides] [(cli-filter)] [(context-filter)] [(report-filter)] command [modifications]
|
task [overrides] [(cli-filter)] [(context-filter)] [(report-filter)] command [modifications]
|
||||||
|
|
||||||
|
@ -158,5 +151,4 @@ Aside from the command line parser, there are other changes needed:
|
||||||
hhmmss # Bad
|
hhmmss # Bad
|
||||||
hh:mm:ss # Good
|
hh:mm:ss # Good
|
||||||
|
|
||||||
- The tutorial videos will be even more out of date, and will be replaced by a
|
- The tutorial videos will be even more out of date, and will be replaced by a large number of smaller demo \'movies\'.
|
||||||
large number of smaller demo \'movies\'.
|
|
||||||
|
|
|
@ -5,48 +5,36 @@ title: "Taskwarrior - Creating a Taskserver Client"
|
||||||
|
|
||||||
# Creating a Taskserver Client
|
# Creating a Taskserver Client
|
||||||
|
|
||||||
A Taskserver client is a todo-list manager. It may be as simple as a program
|
A Taskserver client is a todo-list manager.
|
||||||
that captures a single task, as complex as Taskwarrior, or anything in between.
|
It may be as simple as a program that captures a single task, as complex as Taskwarrior, or anything in between.
|
||||||
It can be a mobile client, a web application, or any other type of program.
|
It can be a mobile client, a web application, or any other type of program.
|
||||||
|
|
||||||
This document describes how such a client would interact with the server.
|
This document describes how such a client would interact with the server.
|
||||||
|
|
||||||
A client to the Taskserver is a program that manages a task list, and wishes to
|
A client to the Taskserver is a program that manages a task list, and wishes to exchange data with the server so that the task list may be shared.
|
||||||
exchange data with the server so that the task list may be shared.
|
|
||||||
|
|
||||||
In order to do this, a client must store tasks locally, upload local changes,
|
In order to do this, a client must store tasks locally, upload local changes, download remote changes, and apply remote changes to the local tasks.
|
||||||
download remote changes, and apply remote changes to the local tasks.
|
|
||||||
|
|
||||||
The client must consider that there may be no network connectivity, or no desire
|
The client must consider that there may be no network connectivity, or no desire by the user to synchronize.
|
||||||
by the user to synchronize.
|
|
||||||
|
|
||||||
The client will need proper credentials to talk to the server.
|
The client will need proper credentials to talk to the server.
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
In this document, we adopt the convention discussed in Section 1.3.2 of
|
In this document, we adopt the convention discussed in Section 1.3.2 of [RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the significance of each particular requirement specified in this document.
|
||||||
[RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized
|
|
||||||
words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the
|
|
||||||
significance of each particular requirement specified in this document.
|
|
||||||
|
|
||||||
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute
|
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there may exist valid reasons for ignoring this item, but the full implications should be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this item is optional, and may be omitted without careful consideration.
|
||||||
requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there
|
|
||||||
may exist valid reasons for ignoring this item, but the full implications should
|
|
||||||
be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this
|
|
||||||
item is optional, and may be omitted without careful consideration.
|
|
||||||
|
|
||||||
|
|
||||||
## Taskserver Account
|
## Taskserver Account
|
||||||
|
|
||||||
A Taskserver account must be created. This process creates a storage area, and
|
A Taskserver account must be created.
|
||||||
generates the necessary credentials.
|
This process creates a storage area, and generates the necessary credentials.
|
||||||
|
|
||||||
|
|
||||||
## Credentials
|
## Credentials
|
||||||
|
|
||||||
A Taskserver client needs the following credentials in order to communicate with
|
A Taskserver client needs the following credentials in order to communicate with a server:
|
||||||
a server:
|
|
||||||
|
|
||||||
- Server address and port
|
- Server address and port
|
||||||
- Organization name
|
- Organization name
|
||||||
|
@ -55,45 +43,44 @@ a server:
|
||||||
- Certificate
|
- Certificate
|
||||||
- Key
|
- Key
|
||||||
|
|
||||||
The server address and port are the network location of the server. An example
|
The server address and port are the network location of the server.
|
||||||
of this value is:
|
An example of this value is:
|
||||||
|
|
||||||
foo.example.com:53589
|
foo.example.com:53589
|
||||||
|
|
||||||
In addition to a DNS name, this can be an IPv4 or IPv6 address.
|
In addition to a DNS name, this can be an IPv4 or IPv6 address.
|
||||||
|
|
||||||
The organization name is an arbitrary grouping, and is typically \'PUBLIC\',
|
The organization name is an arbitrary grouping, and is typically \'PUBLIC\', reflecting the individual nature of server accounts.
|
||||||
reflecting the individual nature of server accounts. Future capabilities will
|
Future capabilities will provide functionality that support groups of users, called an organization.
|
||||||
provide functionality that support groups of users, called an organization.
|
|
||||||
|
|
||||||
The user name is the full name. This will be the name used to identify other
|
The user name is the full name.
|
||||||
users in an organization, in a future release. Example \'John Doe\'.
|
This will be the name used to identify other users in an organization, in a future release.
|
||||||
|
Example \'John Doe\'.
|
||||||
|
|
||||||
The password is a text string generated by the server at account creation time.
|
The password is a text string generated by the server at account creation time.
|
||||||
It should be considered a secret.
|
It should be considered a secret.
|
||||||
|
|
||||||
The certificate is an X.509 PEM file generated by the server at account creation
|
The certificate is an X.509 PEM file generated by the server at account creation time.
|
||||||
time. This is used for authentication. It should be considered a secret.
|
This is used for authentication.
|
||||||
|
It should be considered a secret.
|
||||||
|
|
||||||
The key is an X.509 PEM file generated by the server at account creation time.
|
The key is an X.509 PEM file generated by the server at account creation time.
|
||||||
This is used for encryption. It should be considered a secret.
|
This is used for encryption.
|
||||||
|
It should be considered a secret.
|
||||||
|
|
||||||
These credentials need to be stored on the client, and used during the sync
|
These credentials need to be stored on the client, and used during the sync operation.
|
||||||
operation.
|
|
||||||
|
|
||||||
|
|
||||||
## Description of a Taskserver Client
|
## Description of a Taskserver Client
|
||||||
|
|
||||||
This section describes how a client might behave in order to facilitate
|
This section describes how a client might behave in order to facilitate integration with the Taskserver.
|
||||||
integration with the Taskserver.
|
|
||||||
|
|
||||||
|
|
||||||
## Encryption
|
## Encryption
|
||||||
|
|
||||||
The Taskserver only communicates using encryption. Therefore all user data is
|
The Taskserver only communicates using encryption.
|
||||||
encrypted while in transit. The Taskserver currently uses
|
Therefore all user data is encrypted while in transit.
|
||||||
[GnuTLS](https://gnutls.org) to support this encryption, and therefore supports
|
The Taskserver currently uses [GnuTLS](https://gnutls.org) to support this encryption, and therefore supports the following protocols:
|
||||||
the following protocols:
|
|
||||||
|
|
||||||
- SSL 3.0
|
- SSL 3.0
|
||||||
- TLS 1.0
|
- TLS 1.0
|
||||||
|
@ -105,139 +92,116 @@ The client may use any library that supports the above.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The client needs to store configuration, which matches the credentials needed
|
The client needs to store configuration, which matches the credentials needed for Taskserver communication.
|
||||||
for Taskserver communication. See section 2.1 \"Credentials\".
|
See section 2.1 \"Credentials\".
|
||||||
|
|
||||||
The credentials may not be modified by the user without losing server access.
|
The credentials may not be modified by the user without losing server access.
|
||||||
|
|
||||||
The server:port data may need to be changed automatically following a redirect
|
The server:port data may need to be changed automatically following a redirect response from the server.
|
||||||
response from the server. See section 5 \"Server Errors\".
|
See section 5 \"Server Errors\".
|
||||||
|
|
||||||
|
|
||||||
## Local Storage
|
## Local Storage
|
||||||
|
|
||||||
The client needs to store task data locally. The client will need to be able to
|
The client needs to store task data locally.
|
||||||
find tasks by their UUID and overwrite them. Uploaded and downloaded task
|
The client will need to be able to find tasks by their UUID and overwrite them.
|
||||||
changes will use the [Taskwarrior Data Interchange
|
Uploaded and downloaded task changes will use the [Taskwarrior Data Interchange Format](/docs/design/task).
|
||||||
Format](/docs/design/task).
|
|
||||||
|
|
||||||
|
|
||||||
## Local Changes
|
## Local Changes
|
||||||
|
|
||||||
Whenever local data is modified, that change MUST be synced with the server. But
|
Whenever local data is modified, that change MUST be synced with the server.
|
||||||
this does not have to occur immediately, in fact the client SHOULD NOT assume
|
But this does not have to occur immediately, in fact the client SHOULD NOT assume connectivity at any time.
|
||||||
connectivity at any time.
|
|
||||||
|
|
||||||
A client SHOULD NOT also assume that the server is available. If the server is
|
A client SHOULD NOT also assume that the server is available.
|
||||||
not available, the local changes should be retained, and the sync operation
|
If the server is not available, the local changes should be retained, and the sync operation repeated later.
|
||||||
repeated later.
|
|
||||||
|
|
||||||
Ideally the client will give the user full control over sync operations.
|
Ideally the client will give the user full control over sync operations.
|
||||||
Automatically syncing after all local modifications is not recommended. If a
|
Automatically syncing after all local modifications is not recommended.
|
||||||
client performs too many sync operations, the server MAY revoke the certificate.
|
If a client performs too many sync operations, the server MAY revoke the certificate.
|
||||||
|
|
||||||
Effectively, the client should maintain a separate list of tasks changed since
|
Effectively, the client should maintain a separate list of tasks changed since the last successful sync operation.
|
||||||
the last successful sync operation.
|
|
||||||
|
|
||||||
Note that tasks have a \"modified\" attribute, which should be updated whenever
|
Note that tasks have a \"modified\" attribute, which should be updated whenever a change is made.
|
||||||
a change is made. This attribute contributes to conflict resolution on the
|
This attribute contributes to conflict resolution on the server.
|
||||||
server.
|
|
||||||
|
|
||||||
|
|
||||||
## Remote Changes
|
## Remote Changes
|
||||||
|
|
||||||
When a server sends remote changes to a client, in the response to a sync
|
When a server sends remote changes to a client, in the response to a sync request, the changes have already been merged by the server, and therefore the client should simply store them intact.
|
||||||
request, the changes have already been merged by the server, and therefore the
|
|
||||||
client should simply store them intact.
|
|
||||||
|
|
||||||
Based on the UUID in the task, the client can determine whether a task is new
|
Based on the UUID in the task, the client can determine whether a task is new (and should be added to the local list of tasks), or whether it represents a modification (and should overwrite it\'s existing entry).
|
||||||
(and should be added to the local list of tasks), or whether it represents a
|
|
||||||
modification (and should overwrite it\'s existing entry).
|
|
||||||
|
|
||||||
The client MUST NOT perform any merges.
|
The client MUST NOT perform any merges.
|
||||||
|
|
||||||
|
|
||||||
## Sync Key
|
## Sync Key
|
||||||
|
|
||||||
Whenever a sync is performed, the server responds by sending a sync key and any
|
Whenever a sync is performed, the server responds by sending a sync key and any remote changes.
|
||||||
remote changes. The sync key is important, and should be included in the next
|
The sync key is important, and should be included in the next sync request.
|
||||||
sync request. The client is REQUIRED to store the sync key in every server
|
The client is REQUIRED to store the sync key in every server response message.
|
||||||
response message.
|
|
||||||
|
|
||||||
If a client omits the sync key in a sync message, the response will be a
|
If a client omits the sync key in a sync message, the response will be a complete set of all tasks and modifications.
|
||||||
complete set of all tasks and modifications.
|
|
||||||
|
|
||||||
|
|
||||||
## Data Integrity
|
## Data Integrity
|
||||||
|
|
||||||
Although a task is guaranteed to contain at least \'entry\', \'description\' and
|
Although a task is guaranteed to contain at least \'entry\', \'description\' and \'uuid\' attributes, it may also contain other known fields, and unknown user-defined fields.
|
||||||
\'uuid\' attributes, it may also contain other known fields, and unknown
|
An example might be an attribute named \'estimate\'.
|
||||||
user-defined fields. An example might be an attribute named \'estimate\'.
|
|
||||||
|
|
||||||
If a task is received via sync that contains an attribute named \'estimate\',
|
If a task is received via sync that contains an attribute named \'estimate\', then a client has the responsibility of preserving the attribute intact.
|
||||||
then a client has the responsibility of preserving the attribute intact. If that
|
If that data is shown, then it is assumed to be of type \'string\', which is the format used by JSON for all values.
|
||||||
data is shown, then it is assumed to be of type \'string\', which is the format
|
|
||||||
used by JSON for all values.
|
|
||||||
|
|
||||||
Conversely, if a client wishes to add a custom attribute, it is guaranteed that
|
Conversely, if a client wishes to add a custom attribute, it is guaranteed that the server and other clients will preserve that attribute.
|
||||||
the server and other clients will preserve that attribute.
|
|
||||||
|
|
||||||
Using this rule, two clients of differing capabilities can exchange data and
|
Using this rule, two clients of differing capabilities can exchange data and still maintain custom attributes.
|
||||||
still maintain custom attributes.
|
|
||||||
|
|
||||||
This is a requirement. Any client that does not obey this requirement is broken.
|
This is a requirement.
|
||||||
|
Any client that does not obey this requirement is broken.
|
||||||
|
|
||||||
|
|
||||||
## Synchronizing
|
## Synchronizing
|
||||||
|
|
||||||
Synchronizing with the Taskserver consists of a single transaction. Once an
|
Synchronizing with the Taskserver consists of a single transaction.
|
||||||
encrypted connection is made with the server, the client MUST compose a [sync
|
Once an encrypted connection is made with the server, the client MUST compose a [sync request message](/docs/design/request).
|
||||||
request message](/docs/design/request). This message includes credentials
|
This message includes credentials and local changes.
|
||||||
and local changes. The response message contains status and remote changes,
|
The response message contains status and remote changes, which MUST be stored locally.
|
||||||
which MUST be stored locally.
|
|
||||||
|
|
||||||
|
|
||||||
## Establishing Encrypted Connection
|
## Establishing Encrypted Connection
|
||||||
|
|
||||||
All communication with the Taskserver is encrypted using the certificate and key
|
All communication with the Taskserver is encrypted using the certificate and key provided to each user.
|
||||||
provided to each user. Using the \'server\' configuration setting, establish a
|
Using the \'server\' configuration setting, establish a connection.
|
||||||
connection.
|
|
||||||
|
|
||||||
|
|
||||||
## Sync Request
|
## Sync Request
|
||||||
|
|
||||||
See [sync request message](/docs/design/request). A sync request MUST
|
See [sync request message](/docs/design/request).
|
||||||
contain a sync key if one was provided by a previous sync. A sync request MUST
|
A sync request MUST contain a sync key if one was provided by a previous sync.
|
||||||
contain a list of modified tasks, in JSON format (see [Task
|
A sync request MUST contain a list of modified tasks, in JSON format (see [Task JSON](/docs/design/task)), if local modifications have been made.
|
||||||
JSON](/docs/design/task)), if local modifications have been made.
|
|
||||||
|
|
||||||
|
|
||||||
## Sync Response
|
## Sync Response
|
||||||
|
|
||||||
A sync response WILL contain a \'code\' and \'status\' header variable, WILL
|
A sync response WILL contain a \'code\' and \'status\' header variable, WILL contain a sync key in the payload, and MAY contain a list of tasks from the server in JSON format (see [Task JSON](/docs/design/task)).
|
||||||
contain a sync key in the payload, and MAY contain a list of tasks from the
|
|
||||||
server in JSON format (see [Task JSON](/docs/design/task)).
|
|
||||||
|
|
||||||
|
|
||||||
## Server Messages
|
## Server Messages
|
||||||
|
|
||||||
There are cases when the server needs to inform the user of some condition. This
|
There are cases when the server needs to inform the user of some condition.
|
||||||
may be anticipated server downtime, for example. The response message is
|
This may be anticipated server downtime, for example.
|
||||||
typically not present, but may be present in the header, containing a string:
|
The response message is typically not present, but may be present in the header, containing a string:
|
||||||
|
|
||||||
...
|
...
|
||||||
message: Scheduled maintenance 2013-07-14 08:00UTC for 10 minutes.
|
message: Scheduled maintenance 2013-07-14 08:00UTC for 10 minutes.
|
||||||
...
|
...
|
||||||
|
|
||||||
If such a message is returned by the server, it SHOULD be made available to the
|
If such a message is returned by the server, it SHOULD be made available to the user.
|
||||||
user. This is a recommendation, not a requirement.
|
This is a recommendation, not a requirement.
|
||||||
|
|
||||||
|
|
||||||
## Server Errors
|
## Server Errors
|
||||||
|
|
||||||
The server may generate many errors (See
|
The server may generate many errors (See [Protocol](/docs/design/protocol)), but the following is a list of the ones most in need of special handling:
|
||||||
[Protocol](/docs/design/protocol)), but the following is a list of the ones
|
|
||||||
most in need of special handling:
|
|
||||||
|
|
||||||
- 200 Success
|
- 200 Success
|
||||||
- 201 No change
|
- 201 No change
|
||||||
|
@ -247,11 +211,12 @@ most in need of special handling:
|
||||||
- 432 Account terminated
|
- 432 Account terminated
|
||||||
- 5xx Error
|
- 5xx Error
|
||||||
|
|
||||||
The 200 indicates success, and that a change was recorded. The 201 indicates
|
The 200 indicates success, and that a change was recorded.
|
||||||
success but no changes were necessary. The 301 is a redirect message indicating
|
The 201 indicates success but no changes were necessary.
|
||||||
that the client MUST re-request from a new server. The 43x series messages are
|
The 301 is a redirect message indicating that the client MUST re-request from a new server.
|
||||||
account-related. Any 5xx series code is a server error of some kind. All errors
|
The 43x series messages are account-related.
|
||||||
consist of a code and a status message:
|
Any 5xx series code is a server error of some kind.
|
||||||
|
All errors consist of a code and a status message:
|
||||||
|
|
||||||
code: 200
|
code: 200
|
||||||
status: Success
|
status: Success
|
||||||
|
@ -259,11 +224,10 @@ consist of a code and a status message:
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Here are examples of properly formatted request and response messages. Note that
|
Here are examples of properly formatted request and response messages.
|
||||||
the messages are indented for clarity in this document, but is not the case in a
|
Note that the messages are indented for clarity in this document, but is not the case in a properly formatted message.
|
||||||
properly formatted message. Also note that newline characters U+000D are not
|
Also note that newline characters U+000D are not shown, but are implied by the separate lines.
|
||||||
shown, but are implied by the separate lines. Because some messages have
|
Because some messages have trailing newline characters, the text is delimited by the \'cut\' markers:
|
||||||
trailing newline characters, the text is delimited by the \'cut\' markers:
|
|
||||||
|
|
||||||
foo
|
foo
|
||||||
|
|
||||||
|
@ -275,8 +239,7 @@ The example above illustrates text consisting of:
|
||||||
U+000D newline
|
U+000D newline
|
||||||
U+000D newline
|
U+000D newline
|
||||||
|
|
||||||
Note that these values are left unspecified, but should be clear from the
|
Note that these values are left unspecified, but should be clear from the context, and the [message format](/docs/design/request) spec:
|
||||||
context, and the [message format](/docs/design/request) spec:
|
|
||||||
|
|
||||||
<size>
|
<size>
|
||||||
<organization>
|
<organization>
|
||||||
|
@ -286,8 +249,7 @@ context, and the [message format](/docs/design/request) spec:
|
||||||
|
|
||||||
## First Sync
|
## First Sync
|
||||||
|
|
||||||
The first time a client syncs, there is (perhaps) no data to upload, and no sync
|
The first time a client syncs, there is (perhaps) no data to upload, and no sync key from a previous sync.
|
||||||
key from a previous sync.
|
|
||||||
|
|
||||||
<size>type: sync
|
<size>type: sync
|
||||||
org: <organization>
|
org: <organization>
|
||||||
|
@ -296,15 +258,12 @@ key from a previous sync.
|
||||||
client: task 2.3.0
|
client: task 2.3.0
|
||||||
protocol: v1
|
protocol: v1
|
||||||
|
|
||||||
Note the double newline character separating header from payload, with an empty
|
Note the double newline character separating header from payload, with an empty payload.
|
||||||
payload.
|
|
||||||
|
|
||||||
|
|
||||||
## Request: Sync No Data
|
## Request: Sync No Data
|
||||||
|
|
||||||
Ordinarily when a client syncs, there is a sync key from the previous sync
|
Ordinarily when a client syncs, there is a sync key from the previous sync response to send.
|
||||||
response to send. This example shows a sync with no local changes, but a sync
|
This example shows a sync with no local changes, but a sync key from a previous sync.
|
||||||
key from a previous sync.
|
|
||||||
|
|
||||||
<size>type: sync
|
<size>type: sync
|
||||||
org: <organization>
|
org: <organization>
|
||||||
|
@ -318,8 +277,7 @@ key from a previous sync.
|
||||||
|
|
||||||
## Request: Sync Data
|
## Request: Sync Data
|
||||||
|
|
||||||
This sync request shows a sync key from the previous sync, and a locally
|
This sync request shows a sync key from the previous sync, and a locally modified task.
|
||||||
modified task.
|
|
||||||
|
|
||||||
<size>type: sync
|
<size>type: sync
|
||||||
org: <organization>
|
org: <organization>
|
||||||
|
@ -334,8 +292,7 @@ modified task.
|
||||||
|
|
||||||
## Response: No Data
|
## Response: No Data
|
||||||
|
|
||||||
If a sync results in no downloads to the client, the response will look like
|
If a sync results in no downloads to the client, the response will look like this.
|
||||||
this.
|
|
||||||
|
|
||||||
<size>type: response
|
<size>type: response
|
||||||
client: taskd 1.0.0
|
client: taskd 1.0.0
|
||||||
|
@ -345,14 +302,12 @@ this.
|
||||||
|
|
||||||
45da7110-1bcc-4318-d33e-12267a774e0f
|
45da7110-1bcc-4318-d33e-12267a774e0f
|
||||||
|
|
||||||
Note that there is a sync key which must be stored and used in the next sync
|
Note that there is a sync key which must be stored and used in the next sync request, but there are no remote changes to store.
|
||||||
request, but there are no remote changes to store.
|
|
||||||
|
|
||||||
|
|
||||||
## Response: Remote Data
|
## Response: Remote Data
|
||||||
|
|
||||||
This shows a sync response providing a new sync key, and a remote change to two
|
This shows a sync response providing a new sync key, and a remote change to two tasks.
|
||||||
tasks.
|
|
||||||
|
|
||||||
<size>type: response
|
<size>type: response
|
||||||
client: taskd 1.0.0
|
client: taskd 1.0.0
|
||||||
|
@ -366,8 +321,7 @@ tasks.
|
||||||
|
|
||||||
Note that the sync key must be stored for the next sync request.
|
Note that the sync key must be stored for the next sync request.
|
||||||
|
|
||||||
Note that the two changed tasks must be stored locally, and if the UUID in the
|
Note that the two changed tasks must be stored locally, and if the UUID in the tasks matches local tasks, then the local tasks must be overwritten.
|
||||||
tasks matches local tasks, then the local tasks must be overwritten.
|
|
||||||
|
|
||||||
|
|
||||||
## Response: Error
|
## Response: Error
|
||||||
|
@ -378,8 +332,7 @@ tasks matches local tasks, then the local tasks must be overwritten.
|
||||||
code: 431
|
code: 431
|
||||||
status: Account suspended
|
status: Account suspended
|
||||||
|
|
||||||
Note the double newline character separating header from payload, with an empty
|
Note the double newline character separating header from payload, with an empty payload.
|
||||||
payload.
|
|
||||||
|
|
||||||
|
|
||||||
## Response: Relocate
|
## Response: Relocate
|
||||||
|
@ -391,22 +344,18 @@ payload.
|
||||||
status: Redirect
|
status: Redirect
|
||||||
info:
|
info:
|
||||||
|
|
||||||
Note the \'info\' field will contain a \':\' string that should be used for all
|
Note the \'info\' field will contain a \':\' string that should be used for all future sync requests.
|
||||||
future sync requests. This indicates that a user account was moved to another
|
This indicates that a user account was moved to another server.
|
||||||
server.
|
|
||||||
|
|
||||||
Note the double newline character separating header from payload, with an empty
|
Note the double newline character separating header from payload, with an empty payload.
|
||||||
payload.
|
|
||||||
|
|
||||||
|
|
||||||
## Response: Message
|
## Response: Message
|
||||||
|
|
||||||
Occasionally the server will need to convey a message, and will include an
|
Occasionally the server will need to convey a message, and will include an additional header variable containing that message.
|
||||||
additional header variable containing that message.
|
|
||||||
|
|
||||||
The server [protocol](/docs/design/protocol) states that the message SHOULD
|
The server [protocol](/docs/design/protocol) states that the message SHOULD be shown to the user.
|
||||||
be shown to the user. This message will be used for system event messages, used
|
This message will be used for system event messages, used rarely, and never used for advertising or promotion.
|
||||||
rarely, and never used for advertising or promotion.
|
|
||||||
|
|
||||||
<size>type: response
|
<size>type: response
|
||||||
client: taskd 1.0.0
|
client: taskd 1.0.0
|
||||||
|
@ -422,8 +371,7 @@ Note that the same message will likely be included in consecutive responses.
|
||||||
|
|
||||||
## Reference Implementation
|
## Reference Implementation
|
||||||
|
|
||||||
The Taskserver 1.1.0 codebase contains a reference implementation of an SSL/TLS
|
The Taskserver 1.1.0 codebase contains a reference implementation of an SSL/TLS client and server program, which communicate text strings.
|
||||||
client and server program, which communicate text strings.
|
|
||||||
|
|
||||||
taskd.git/src/tls/Makefile # To build the example
|
taskd.git/src/tls/Makefile # To build the example
|
||||||
taskd.git/src/tls/README # How to run the example
|
taskd.git/src/tls/README # How to run the example
|
||||||
|
|
|
@ -4,14 +4,14 @@ title: "Taskwarrior - Full DOM Support"
|
||||||
|
|
||||||
## Work in Progress
|
## Work in Progress
|
||||||
|
|
||||||
This design document is a work in progress, and subject to change. Once
|
This design document is a work in progress, and subject to change.
|
||||||
finalized, the feature will be scheduled for an upcoming release.
|
Once finalized, the feature will be scheduled for an upcoming release.
|
||||||
|
|
||||||
|
|
||||||
# Full DOM Support
|
# Full DOM Support
|
||||||
|
|
||||||
Taskwarrior currently supports DOM references that can access any stored data
|
Taskwarrior currently supports DOM references that can access any stored data item.
|
||||||
item. The general forms supported are:
|
The general forms supported are:
|
||||||
|
|
||||||
[ <id> | <uuid> ] <attribute> [ <part> ]
|
[ <id> | <uuid> ] <attribute> [ <part> ]
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@ Examples include:
|
||||||
123.annotations.0.entry.year
|
123.annotations.0.entry.year
|
||||||
a87bc10f-931b-4558-a44a-e901a77db011.description
|
a87bc10f-931b-4558-a44a-e901a77db011.description
|
||||||
|
|
||||||
Additionally there are references for accessing configuration and system/program
|
Additionally there are references for accessing configuration and system/program level items.
|
||||||
level items.
|
|
||||||
|
|
||||||
rc.<name>
|
rc.<name>
|
||||||
context.program
|
context.program
|
||||||
|
@ -34,10 +33,8 @@ level items.
|
||||||
system.version
|
system.version
|
||||||
system.os
|
system.os
|
||||||
|
|
||||||
While this is adequate for data retrieval, we have the possibility of extending
|
While this is adequate for data retrieval, we have the possibility of extending it further to include data formats, higher-level constructs, and then to make use of DOM references in more locations.
|
||||||
it further to include data formats, higher-level constructs, and then to make
|
This contributes to our goal of simplifying Taskwarrior.
|
||||||
use of DOM references in more locations. This contributes to our goal of
|
|
||||||
simplifying Taskwarrior.
|
|
||||||
|
|
||||||
|
|
||||||
## Proposed Format Support
|
## Proposed Format Support
|
||||||
|
@ -50,12 +47,11 @@ This syntax is:
|
||||||
|
|
||||||
<attribute> [ . <format> ]
|
<attribute> [ . <format> ]
|
||||||
|
|
||||||
If no `format` is specified, then `default` is assumed. The src/columns/ColΧ\*
|
If no `format` is specified, then `default` is assumed.
|
||||||
objects are responsible for supporting and rendering these formats. There is
|
The `src/columns/ColΧ\*` objects are responsible for supporting and rendering these formats.
|
||||||
currently no consistency among these formats based on data type.
|
There is currently no consistency among these formats based on data type.
|
||||||
|
|
||||||
By incorporating formats into DOM references, we eliminate the need for a
|
By incorporating formats into DOM references, we eliminate the need for a separate syntax for custom reports, and provide this:
|
||||||
separate syntax for custom reports, and provide this:
|
|
||||||
|
|
||||||
123.due.iso
|
123.due.iso
|
||||||
123.due.month.short
|
123.due.month.short
|
||||||
|
@ -161,8 +157,7 @@ json
|
||||||
|
|
||||||
`"<attribute>":"<value>"`
|
`"<attribute>":"<value>"`
|
||||||
|
|
||||||
There will also be a set of attribute-specific formats, similar to the currently
|
There will also be a set of attribute-specific formats, similar to the currently supported set:
|
||||||
supported set:
|
|
||||||
|
|
||||||
depends.list
|
depends.list
|
||||||
depends.count
|
depends.count
|
||||||
|
@ -186,21 +181,19 @@ supported set:
|
||||||
uuid.default|long
|
uuid.default|long
|
||||||
uuid.short
|
uuid.short
|
||||||
|
|
||||||
Custom report sort criteria will also use DOM references. This will be augmented
|
Custom report sort criteria will also use DOM references.
|
||||||
by the `+`/`-` sort direction and `/` break indicator, which are not part of the
|
This will be augmented by the `+`/`-` sort direction and `/` break indicator, which are not part of the DOM.
|
||||||
DOM.
|
|
||||||
|
|
||||||
|
|
||||||
## High Level Construct Support
|
## High Level Construct Support
|
||||||
|
|
||||||
There need to be read-only DOM references that do not correspond directly to
|
There need to be read-only DOM references that do not correspond directly to stored attributes.
|
||||||
stored attributes. Tasks have emergent properties represented by virtual tags,
|
Tasks have emergent properties represented by virtual tags, which will be accessible, in this case returning a `0` or `1`:
|
||||||
which will be accessible, in this case returning a `0` or `1`:
|
|
||||||
|
|
||||||
123.tags.OVERDUE
|
123.tags.OVERDUE
|
||||||
|
|
||||||
Using `rc.due` and the `due` attribute, the `OVERDUE` virtual tag is a
|
Using `rc.due` and the `due` attribute, the `OVERDUE` virtual tag is a combination of the two.
|
||||||
combination of the two. Other examples may include:
|
Other examples may include:
|
||||||
|
|
||||||
task.syncneeded
|
task.syncneeded
|
||||||
task.pending.count
|
task.pending.count
|
||||||
|
@ -209,8 +202,8 @@ combination of the two. Other examples may include:
|
||||||
|
|
||||||
## Writable References
|
## Writable References
|
||||||
|
|
||||||
When a DOM reference refers to an attribute or RC setting, and does not extend
|
When a DOM reference refers to an attribute or RC setting, and does not extend further and reference a component or format, it may be writable.
|
||||||
further and reference a component or format, it may be writable. For example:
|
For example:
|
||||||
|
|
||||||
rc.hooks # writable
|
rc.hooks # writable
|
||||||
123.description # writable
|
123.description # writable
|
||||||
|
@ -219,8 +212,7 @@ further and reference a component or format, it may be writable. For example:
|
||||||
|
|
||||||
## Data Interchange
|
## Data Interchange
|
||||||
|
|
||||||
The export command can be used to show a filtered set of tasks in JSON format,
|
The export command can be used to show a filtered set of tasks in JSON format, and this will also be available as a DOM format:
|
||||||
and this will also be available as a DOM format:
|
|
||||||
|
|
||||||
123.json
|
123.json
|
||||||
a87bc10f-931b-4558-a44a-e901a77db011.json
|
a87bc10f-931b-4558-a44a-e901a77db011.json
|
||||||
|
@ -228,32 +220,30 @@ and this will also be available as a DOM format:
|
||||||
|
|
||||||
## RC File Support
|
## RC File Support
|
||||||
|
|
||||||
The RC file (`~/.taskrc`) will support DOM references in values. This will form
|
The RC file (`~/.taskrc`) will support DOM references in values.
|
||||||
a late-bound reference, which is evaluated at runtime, every time.
|
This will form a late-bound reference, which is evaluated at runtime, every time.
|
||||||
|
|
||||||
An example is to make two reports share the same description:
|
An example is to make two reports share the same description:
|
||||||
|
|
||||||
$ task config -- report.ls.description rc.report.list.description
|
$ task config -- report.ls.description rc.report.list.description
|
||||||
|
|
||||||
This sets the description for the `ls` report to be a reference to the
|
This sets the description for the `ls` report to be a reference to the description of the `list` report.
|
||||||
description of the `list` report. This reference is not evaluated when the entry
|
This reference is not evaluated when the entry is written, but is evaluated every time the value is read, thus providing late-bound behavior.
|
||||||
is written, but is evaluated every time the value is read, thus providing
|
Then if the description of the `list` report changes, so does that of the `ls` report automatically.
|
||||||
late-bound behavior. Then if the description of the `list` report changes, so
|
|
||||||
does that of the `ls` report automatically.
|
|
||||||
|
|
||||||
|
|
||||||
## Implementation Details
|
## Implementation Details
|
||||||
|
|
||||||
These notes list a series of anticipated changes to the codebase.
|
These notes list a series of anticipated changes to the codebase.
|
||||||
|
|
||||||
- The `src/columns/Col*` objects will implement type-specific and
|
- The `src/columns/Col*` objects will implement type-specific and attribute-specific DOM support.
|
||||||
attribute-specific DOM support. DOM reference lookup will defer to the
|
DOM reference lookup will defer to the column objects first.
|
||||||
column objects first.
|
|
||||||
- Some DOM references will be writable, permitting a `_set` command to
|
- Some DOM references will be writable, permitting a `_set` command to complement the `_get` command.
|
||||||
complement the `_get` command.
|
|
||||||
- The `Config` object will recognize DOM references in values and perform
|
- The `Config` object will recognize DOM references in values and perform lookup at read time.
|
||||||
lookup at read time. This will require circularity detection.
|
This will require circularity detection.
|
||||||
- `src/DOM.cpp` will provide a memoized function to determine whether a DOM
|
|
||||||
reference is valid.
|
- `src/DOM.cpp` will provide a memoized function to determine whether a DOM reference is valid.
|
||||||
- `src/DOM.cpp` will provide a function to obtain a DOM reference value, with
|
|
||||||
supporting metadata (type, writable).
|
- `src/DOM.cpp` will provide a function to obtain a DOM reference value, with supporting metadata (type, writable).
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
title: "Plans"
|
title: "Plans"
|
||||||
---
|
---
|
||||||
|
|
||||||
There are many interconnected features and technologies in Taskwarrior,
|
There are many interconnected features and technologies in Taskwarrior, Taskserver, Tasksh and Timewarrior, each piece having it's own goals.
|
||||||
Taskserver, Tasksh and Timewarrior, each piece having it's own goals.
|
|
||||||
|
|
||||||
This matrix allows a simple reading of where things are, and where they are
|
This matrix allows a simple reading of where things are, and where they are going.
|
||||||
going. This is a low-resolution time line. It is subject to change. It does not
|
This is a low-resolution time line.
|
||||||
constitute a concrete plan. This is an all-volunteer effort, and scheduling is
|
It is subject to change.
|
||||||
difficult.
|
It does not constitute a concrete plan.
|
||||||
|
This is an all-volunteer effort, and scheduling is difficult.
|
||||||
|
|
||||||
[Last updated 2016-08-08.]
|
[Last updated 2016-08-08.]
|
||||||
|
|
||||||
|
|
|
@ -8,204 +8,164 @@ title: "Taskwarrior - Sync Protocol"
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
Taskwarrior data has typically been shared in several ways. Those include SCM
|
Taskwarrior data has typically been shared in several ways.
|
||||||
(source code management) systems, directory synchronizing software (such as
|
Those include SCM (source code management) systems, directory synchronizing software (such as DropBox), and by use of the \'push\', \'pull\' and \'merge\' commands introduced in version 1.9.3.
|
||||||
DropBox), and by use of the \'push\', \'pull\' and \'merge\' commands introduced
|
|
||||||
in version 1.9.3.
|
|
||||||
|
|
||||||
While these methods work, they each have problems associated with the merging of
|
While these methods work, they each have problems associated with the merging of data.
|
||||||
data. In the case of directory synchronizing software, there is no merging at
|
In the case of directory synchronizing software, there is no merging at all - just simple file overwrite, despite many people believing that the data is somehow combined and preserved.
|
||||||
all - just simple file overwrite, despite many people believing that the data is
|
|
||||||
somehow combined and preserved.
|
|
||||||
|
|
||||||
The Taskserver is a solution. It is an online/cloud storage and sync service for
|
The Taskserver is a solution.
|
||||||
taskwarrior data. It performs conflict-free data merging, and minimizes
|
It is an online/cloud storage and sync service for taskwarrior data.
|
||||||
bandwidth use.
|
It performs conflict-free data merging, and minimizes bandwidth use.
|
||||||
|
|
||||||
The Taskserver also provides multi-client access, so that a task added using a
|
The Taskserver also provides multi-client access, so that a task added using a web client could be immediately viewed using a mobile client, or modified using taskwarrior.
|
||||||
web client could be immediately viewed using a mobile client, or modified using
|
Choice of clients is important - people have widely varying behaviors and tastes.
|
||||||
taskwarrior. Choice of clients is important - people have widely varying
|
|
||||||
behaviors and tastes.
|
|
||||||
|
|
||||||
The Taskserver also provides multi-user access, which introduces new
|
The Taskserver also provides multi-user access, which introduces new capabilities, such as list sharing and delegation.
|
||||||
capabilities, such as list sharing and delegation. These will require later
|
These will require later modification to this protocol.
|
||||||
modification to this protocol.
|
|
||||||
|
|
||||||
The Taskserver protocol will be implemented by the taskd project and first used
|
The Taskserver protocol will be implemented by the taskd project and first used in taskwarrior 2.3.0.
|
||||||
in taskwarrior 2.3.0. Other clients will follow.
|
Other clients will follow.
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
In this document, we adopt the convention discussed in Section 1.3.2 of
|
In this document, we adopt the convention discussed in Section 1.3.2 of [RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the significance of each particular requirement specified in this document.
|
||||||
[RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized
|
|
||||||
words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the
|
|
||||||
significance of each particular requirement specified in this document.
|
|
||||||
|
|
||||||
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute
|
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there may exist valid reasons for ignoring this item, but the full implications should be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this item is optional, and may be omitted without careful consideration.
|
||||||
requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there
|
|
||||||
may exist valid reasons for ignoring this item, but the full implications should
|
|
||||||
be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this
|
|
||||||
item is optional, and may be omitted without careful consideration.
|
|
||||||
|
|
||||||
|
|
||||||
## Link Level
|
## Link Level
|
||||||
|
|
||||||
The Taskserver protocol assumes a reliable data stream such as provided by TCP.
|
The Taskserver protocol assumes a reliable data stream such as provided by TCP.
|
||||||
When TCP is used, a Taskserver listens on a single predetermined port *for the
|
When TCP is used, a Taskserver listens on a single predetermined port *for the given client* only.
|
||||||
given client* only. This means the server may be using multiple ports to serve
|
This means the server may be using multiple ports to serve distinct sets of clients.
|
||||||
distinct sets of clients.
|
|
||||||
|
|
||||||
This server is only an interface between programs and the task data. It does not
|
This server is only an interface between programs and the task data.
|
||||||
perform any user interaction or presentation-level functions.
|
It does not perform any user interaction or presentation-level functions.
|
||||||
|
|
||||||
|
|
||||||
## Transactions
|
## Transactions
|
||||||
|
|
||||||
Each transaction is a single incoming message, with a single response message.
|
Each transaction is a single incoming message, with a single response message.
|
||||||
All communication therefore consists of a single \'send\', followed by a single
|
All communication therefore consists of a single \'send\', followed by a single \'receive\', then termination.
|
||||||
\'receive\', then termination. There are no sessions, and no continuously open
|
There are no sessions, and no continuously open connections.
|
||||||
connections. The message format is described in the [Taskserver Message
|
The message format is described in the [Taskserver Message Format](/docs/design/request) document.
|
||||||
Format](/docs/design/request) document.
|
|
||||||
|
|
||||||
|
|
||||||
## Responsibilities of the Server
|
## Responsibilities of the Server
|
||||||
|
|
||||||
The server will maintain a set of transactions, in the original sequence,
|
The server will maintain a set of transactions, in the original sequence, punctuated by sync keys which are UUIDs.
|
||||||
punctuated by sync keys which are UUIDs. Each sync key represents a non- trivial
|
Each sync key represents a non- trivial sync operation by a client.
|
||||||
sync operation by a client. Each transaction is a [JSON-formatted
|
Each transaction is a [JSON-formatted task](/docs/design/task), followed by a newline (\\n) character.
|
||||||
task](/docs/design/task), followed by a newline (\\n) character. The result
|
The result is a single file that contains interleaved lines of two types: tasks and sync keys.
|
||||||
is a single file that contains interleaved lines of two types: tasks and sync
|
|
||||||
keys.
|
|
||||||
|
|
||||||
This design allows the server to maintain a set of deltas such that multiple
|
This design allows the server to maintain a set of deltas such that multiple clients may request a minimal set of changes since their last sync.
|
||||||
clients may request a minimal set of changes since their last sync.
|
|
||||||
|
|
||||||
|
|
||||||
## Responsibilities of the Client
|
## Responsibilities of the Client
|
||||||
|
|
||||||
This describes how Taskwarrior implements sync.
|
This describes how Taskwarrior implements sync.
|
||||||
|
|
||||||
All modifications to tasks (add, modify, done, delete \...) are recorded in the
|
All modifications to tasks (add, modify, done, delete \...) are recorded in the form of a fully-composed [JSON-formatted task](/docs/design/task).
|
||||||
form of a fully-composed [JSON-formatted task](/docs/design/task). The
|
The formatted task is added to a local backlog.data file.
|
||||||
formatted task is added to a local backlog.data file. If a task is modified a
|
If a task is modified a second time, it is added again to the backlog.data file - the lines are not combined.
|
||||||
second time, it is added again to the backlog.data file - the lines are not
|
Each task SHALL have a \'modified\' date attribute that will help resolve conflicts.
|
||||||
combined. Each task SHALL have a \'modified\' date attribute that will help
|
|
||||||
resolve conflicts.
|
|
||||||
|
|
||||||
On sync:
|
On sync:
|
||||||
|
|
||||||
- Send a \'sync\' type message with the entire contents of the backlog.data,
|
- Send a \'sync\' type message with the entire contents of the backlog.data, unmodified, as the message payload.
|
||||||
unmodified, as the message payload.
|
|
||||||
- Receive one of the following response codes:
|
- Receive one of the following response codes:
|
||||||
- 201: This means \'no change\', and there is no further action to be
|
|
||||||
taken.
|
- 201: This means \'no change\', and there is no further action to be taken.
|
||||||
- 200: This means \'success\', and the message payload contains a set of
|
|
||||||
tasks and a sync key:
|
- 200: This means \'success\', and the message payload contains a set of tasks and a sync key:
|
||||||
- The formatted tasks are to be stored as-is. These tasks will either
|
|
||||||
be appended to the client data or will overwrite existing client
|
- The formatted tasks are to be stored as-is.
|
||||||
data, based on the UUID of the task. No merge logic is necessary.
|
These tasks will either be appended to the client data or will overwrite existing client data, based on the UUID of the task.
|
||||||
- The sync key will be written to the backlog.data file, overwriting
|
No merge logic is necessary.
|
||||||
the previous contents, such that it will now contain only one line.
|
|
||||||
- 301: Redirect to : found in the \'info\' response header, will force the
|
- The sync key will be written to the backlog.data file, overwriting the previous contents, such that it will now contain only one line.
|
||||||
client to resubmit the request to the new server.
|
|
||||||
|
- 301: Redirect to : found in the \'info\' response header, will force the client to resubmit the request to the new server.
|
||||||
|
|
||||||
- 3xx, 4xx, 5xx: The \'status\' field contains an error message.
|
- 3xx, 4xx, 5xx: The \'status\' field contains an error message.
|
||||||
- If the response contained any error or warning, the error should be shown to
|
|
||||||
the user. This provides an opportunity for the server to announce downtime,
|
|
||||||
or relocation.
|
|
||||||
|
|
||||||
If no sync key is sent, the server cannot provide an incremental delta, and so
|
- If the response contained any error or warning, the error should be shown to the user.
|
||||||
will send all task data, which should be stored as above. This should be the
|
This provides an opportunity for the server to announce downtime, or relocation.
|
||||||
case for a client making its first sync call.
|
|
||||||
|
|
||||||
If an unrecognized attribute is present in the task data, the client MUST
|
If no sync key is sent, the server cannot provide an incremental delta, and so will send all task data, which should be stored as above.
|
||||||
preserve the attribute unmodified, and assume it is of type \'string\'. This
|
This should be the case for a client making its first sync call.
|
||||||
permits individual clients to augment the task data without other clients
|
|
||||||
stripping it meaningful data. This is how UDAs (user defined attributes) are
|
If an unrecognized attribute is present in the task data, the client MUST preserve the attribute unmodified, and assume it is of type \'string\'.
|
||||||
handled.
|
This permits individual clients to augment the task data without other clients stripping it meaningful data.
|
||||||
|
This is how UDAs (user defined attributes) are handled.
|
||||||
|
|
||||||
|
|
||||||
## Extensions
|
## Extensions
|
||||||
|
|
||||||
This protocol was designed so that extensions to the protocol will take the form
|
This protocol was designed so that extensions to the protocol will take the form of additional message types and status codes.
|
||||||
of additional message types and status codes.
|
|
||||||
|
|
||||||
|
|
||||||
## Summary of Response Codes
|
## Summary of Response Codes
|
||||||
|
|
||||||
Status responses indicate the server\'s response to the last command received
|
Status responses indicate the server\'s response to the last command received from the client.
|
||||||
from the client. The codes consist of a 3 digit numeric code.
|
The codes consist of a 3 digit numeric code.
|
||||||
|
|
||||||
The first digit of the response broadly indicates the success, failure, or
|
The first digit of the response broadly indicates the success, failure, or progress of the previous command (based generally on [RFC640](https://tools.ietf.org/html/rfc640) [RFC821](https://tools.ietf.org/html/rfc821)):
|
||||||
progress of the previous command (based generally on
|
|
||||||
[RFC640](https://tools.ietf.org/html/rfc640)
|
|
||||||
[RFC821](https://tools.ietf.org/html/rfc821)):
|
|
||||||
|
|
||||||
----- -------------------------------------
|
| 1yz | Positive Preliminary reply |
|
||||||
1yz Positive Preliminary reply
|
| 2yz | Positive Completion reply |
|
||||||
2yz Positive Completion reply
|
| 3yz | Positive Intermediate reply |
|
||||||
3yz Positive Intermediate reply
|
| 4yz | Transient Negative Completion reply |
|
||||||
4yz Transient Negative Completion reply
|
| 5yz | Permanent Negative Completion reply |
|
||||||
5yz Permanent Negative Completion reply
|
|
||||||
----- -------------------------------------
|
|
||||||
|
|
||||||
The next digit in the code indicates the response category:
|
The next digit in the code indicates the response category:
|
||||||
|
|
||||||
----- -------------------------------------------------
|
| x0z | Syntax |
|
||||||
x0z Syntax
|
| x1z | Information (e.g., help) |
|
||||||
x1z Information (e.g., help)
|
| x2z | Connections |
|
||||||
x2z Connections
|
| x3z | Authentication |
|
||||||
x3z Authentication
|
| x4z | Unspecified as yet |
|
||||||
x4z Unspecified as yet
|
| x5z | Taskd System (\...) |
|
||||||
x5z Taskd System (\...)
|
| x8z | Nonstandard (private implementation) extensions |
|
||||||
x8z Nonstandard (private implementation) extensions
|
|
||||||
----- -------------------------------------------------
|
|
||||||
|
|
||||||
A summary of all status response are:
|
A summary of all status response are:
|
||||||
|
|
||||||
----- -----------
|
| 200 | Success |
|
||||||
200 Success
|
| 201 | No change |
|
||||||
201 No change
|
| 300 | Deprecated message type. This message will not be supported in future Taskserver releases. |
|
||||||
----- -----------
|
| 301 | Redirect. Further requests should be made to the specified server/port. |
|
||||||
|
| 302 | Retry. The client is requested to wait and retry the same request. The wait time is not specified, and further retry responses are possible. |
|
||||||
----- ----------------------------------------------------------------------------------------------------------------------------------------------
|
| 400 | Malformed data |
|
||||||
300 Deprecated message type. This message will not be supported in future Taskserver releases.
|
| 401 | Unsupported encoding |
|
||||||
301 Redirect. Further requests should be made to the specified server/port.
|
| 420 | Server temporarily unavailable |
|
||||||
302 Retry. The client is requested to wait and retry the same request. The wait time is not specified, and further retry responses are possible.
|
| 421 | Server shutting down at operator request |
|
||||||
----- ----------------------------------------------------------------------------------------------------------------------------------------------
|
| 430 | Access denied |
|
||||||
|
| 431 | Account suspended |
|
||||||
----- ------------------------------------------
|
| 432 | Account terminated |
|
||||||
400 Malformed data
|
| 500 | Syntax error in request |
|
||||||
401 Unsupported encoding
|
| 501 | Syntax error, illegal parameters |
|
||||||
420 Server temporarily unavailable
|
| 502 | Not implemented |
|
||||||
421 Server shutting down at operator request
|
| 503 | Command parameter not implemented |
|
||||||
430 Access denied
|
| 504 | Request too big |
|
||||||
431 Account suspended
|
|
||||||
432 Account terminated
|
|
||||||
----- ------------------------------------------
|
|
||||||
|
|
||||||
----- -----------------------------------
|
|
||||||
500 Syntax error in request
|
|
||||||
501 Syntax error, illegal parameters
|
|
||||||
502 Not implemented
|
|
||||||
503 Command parameter not implemented
|
|
||||||
504 Request too big
|
|
||||||
----- -----------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
All communication with the Taskserver uses SSL 3.0 or TLS 1.0, 1.1 or 1.2.
|
All communication with the Taskserver uses SSL 3.0 or TLS 1.0, 1.1 or 1.2.
|
||||||
Encryption is mandatory. Data is never transmitted in plain text.
|
Encryption is mandatory.
|
||||||
|
Data is never transmitted in plain text.
|
||||||
|
|
||||||
|
|
||||||
## Limitations and Guidelines
|
## Limitations and Guidelines
|
||||||
|
|
||||||
Some limitations exists to reduce bandwidth and load on the server. They are:
|
Some limitations exists to reduce bandwidth and load on the server.
|
||||||
|
They are:
|
||||||
|
|
||||||
- A client may only connect to a single server. Synchronization among a set of
|
- A client may only connect to a single server.
|
||||||
servers is not supported.
|
Synchronization among a set of servers is not supported.
|
||||||
- A client should attempt to minimize data bandwidth usage by maintaining a
|
|
||||||
local data store, and properly using sync keys.
|
- A client should attempt to minimize data bandwidth usage by maintaining a local data store, and properly using sync keys.
|
||||||
- A client should minimize data transfers by limiting the frequency of sync
|
|
||||||
requests.
|
- A client should minimize data transfers by limiting the frequency of sync requests.
|
||||||
|
|
|
@ -4,8 +4,8 @@ title: "Taskwarrior - Recurrence"
|
||||||
|
|
||||||
# Draft
|
# Draft
|
||||||
|
|
||||||
This is a draft design document. Your
|
This is a draft design document.
|
||||||
[feedback](mailto:support@taskwarrior.org?Subject=Feedback) is welcomed.
|
Your [feedback](mailto:support@taskwarrior.org?Subject=Feedback) is welcomed.
|
||||||
|
|
||||||
Recurrence
|
Recurrence
|
||||||
----------
|
----------
|
||||||
|
@ -15,54 +15,51 @@ Recurrence needs an overhaul to improve weaknesses and add new features.
|
||||||
# Terminology
|
# Terminology
|
||||||
|
|
||||||
- The hidden 'parent' task is called the template.
|
- The hidden 'parent' task is called the template.
|
||||||
- Synthesis is the name for the generation of new recurring task instances
|
- Synthesis is the name for the generation of new recurring task instances when necessary.
|
||||||
when necessary.
|
|
||||||
- The synthesized tasks are called instances.
|
- The synthesized tasks are called instances.
|
||||||
- The index is the zero-based monotonically increasing number of the instance.
|
- The index is the zero-based monotonically increasing number of the instance.
|
||||||
- Drift is the accumulated errors in time that cause a due date to slowly
|
- Drift is the accumulated errors in time that cause a due date to slowly change for each recurring task.
|
||||||
change for each recurring task.
|
|
||||||
|
|
||||||
# Criticism of Current Implementation
|
# Criticism of Current Implementation
|
||||||
|
|
||||||
- The `mask` attribute grows unbounded.
|
- The `mask` attribute grows unbounded.
|
||||||
- Only strict recurrence cycles are supported. The example of mowing the lawn
|
- Only strict recurrence cycles are supported.
|
||||||
is that you want to mow the lawn every seven days, but when you are four
|
The example of mowing the lawn is that you want to mow the lawn every seven days, but when you are four days late mowing the lawn, the next mowing should be in seven days, not in three.
|
||||||
days late mowing the lawn, the next mowing should be in seven days, not in
|
- Intances generated on one machine and then synced, may collide with equivalent unsynced instances tasks on another device, because the UUIDs are different.
|
||||||
three.
|
- You cannot `wait` a recurring task and have that wait period propagate to all other child tasks.
|
||||||
- Intances generated on one machine and then synced, may collide with
|
|
||||||
equivalent unsynced instances tasks on another device, because the UUIDs are
|
|
||||||
different.
|
|
||||||
- You cannot `wait` a recurring task and have that wait period propagate to
|
|
||||||
all other child tasks.
|
|
||||||
- Task instances cannot individually expire.
|
- Task instances cannot individually expire.
|
||||||
|
|
||||||
# Proposals
|
# Proposals
|
||||||
|
|
||||||
## Proposal: Eliminate `mask`, `imaѕk` Attributes
|
## Proposal: Eliminate `mask`, `imaѕk` Attributes
|
||||||
|
|
||||||
The `mask` attribute in the template is replaced by `last`, which indicates the
|
The `mask` attribute in the template is replaced by `last`, which indicates the most recent instance index synthesized.
|
||||||
most recent instance index synthesized. Because instances are never synthesized
|
Because instances are never synthesized out of order, we only need to store the most recent index.
|
||||||
out of order, we only need to store the most recent index. The `imask` attribute
|
The `imask` attribute in the instance is no longer needed.
|
||||||
in the instance is no longer needed.
|
|
||||||
|
|
||||||
## Proposal: Rename `parent` to `template`
|
## Proposal: Rename `parent` to `template`
|
||||||
|
|
||||||
The name `parent` implies subtasks, and confuses those who inspect the
|
The name `parent` implies subtasks, and confuses those who inspect the internals.
|
||||||
internals. The value remains the UUID of the template. This frees up the
|
The value remains the UUID of the template.
|
||||||
namespace for future use with subtasks.
|
This frees up the namespace for future use with subtasks.
|
||||||
|
|
||||||
## Proposal: New 'rtype' attribute
|
## Proposal: New 'rtype' attribute
|
||||||
|
|
||||||
To indicate the flavor of recurrence, support the following values:
|
To indicate the flavor of recurrence, support the following values:
|
||||||
|
|
||||||
* `periodic` - Instances are created on a regular schedule. Example: send birthday flowers. It must occur on a regular schedule, and doesn't matter if you were late last year. This is the default value.
|
* `periodic` - Instances are created on a regular schedule.
|
||||||
* `chained` - Instances are created back to back, so when one instance ends, the next begins, with the same recurrence. Example: mow the lawn. If you mow two days late, the next instance is not two days early to compensate.
|
Example: send birthday flowers.
|
||||||
|
It must occur on a regular schedule, and doesn't matter if you were late last year.
|
||||||
|
This is the default value.
|
||||||
|
|
||||||
|
* `chained` - Instances are created back to back, so when one instance ends, the next begins, with the same recurrence.
|
||||||
|
Example: mow the lawn.
|
||||||
|
If you mow two days late, the next instance is not two days early to compensate.
|
||||||
|
|
||||||
## Proposal: Use relative offsets
|
## Proposal: Use relative offsets
|
||||||
|
|
||||||
The delta between `wait` and `due` date in the template should be reflected in
|
The delta between `wait` and `due` date in the template should be reflected in the delta between `wait` and `due` date in the instance.
|
||||||
the delta between `wait` and `due` date in the instance. Similarly,
|
Similarly, 'scheduled' must be handled the same way.
|
||||||
'scheduled' must be handled the same way.
|
|
||||||
|
|
||||||
## Proposal: On load, auto-upgrade legacy tasks
|
## Proposal: On load, auto-upgrade legacy tasks
|
||||||
|
|
||||||
|
@ -77,14 +74,12 @@ Upgrade instance:
|
||||||
- Rename `parent` to `template`
|
- Rename `parent` to `template`
|
||||||
- Delete `imask`
|
- Delete `imask`
|
||||||
- Update `wait` if not set to: `wait:due + (template.due - template.wait)`
|
- Update `wait` if not set to: `wait:due + (template.due - template.wait)`
|
||||||
- Update `scheduled` if not set to:
|
- Update `scheduled` if not set to: `scheduled:due + (template.due - template.scheduled)`
|
||||||
`scheduled:due + (template.due - template.scheduled)`
|
|
||||||
|
|
||||||
## Proposal: Deleting a chained instance
|
## Proposal: Deleting a chained instance
|
||||||
|
|
||||||
Deleting a `rtype:chained` instance causes the next chained instance to be
|
Deleting a `rtype:chained` instance causes the next chained instance to be synthesized.
|
||||||
synthesized. This gives the illusion that the due date is simply pushed out to
|
This gives the illusion that the due date is simply pushed out to `(now + template.recur)`.
|
||||||
`(now + template.recur)`.
|
|
||||||
|
|
||||||
## Proposal: Modification Propagation
|
## Proposal: Modification Propagation
|
||||||
|
|
||||||
|
@ -189,14 +184,11 @@ Certain recurrence periods are inexact:
|
||||||
- P1Y
|
- P1Y
|
||||||
- P1D
|
- P1D
|
||||||
|
|
||||||
When the recurrence period is `P1M` the number of days in a month varies and
|
When the recurrence period is `P1M` the number of days in a month varies and causes drift.
|
||||||
causes drift.
|
|
||||||
|
|
||||||
When the recurrence period is `P1Y` the number of days in a year varies and
|
When the recurrence period is `P1Y` the number of days in a year varies and causes drift.
|
||||||
causes drift.
|
|
||||||
|
|
||||||
When the recurrence period is `P1D` the number of hours in a day varies due to
|
When the recurrence period is `P1D` the number of hours in a day varies due to daylight savings, and causes drift.
|
||||||
daylight savings, and causes drift.
|
|
||||||
|
|
||||||
Drift should be avoided by carefully implementing:
|
Drift should be avoided by carefully implementing:
|
||||||
|
|
||||||
|
|
|
@ -2,41 +2,29 @@
|
||||||
title: "Taskwarrior - Request"
|
title: "Taskwarrior - Request"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
# Taskserver Message Format
|
# Taskserver Message Format
|
||||||
|
|
||||||
The Taskserver accepts and emits only messages. These messages look somewhat
|
The Taskserver accepts and emits only messages.
|
||||||
like email, as defined in [RFC821](https://tools.ietf.org/html/rfc821),
|
These messages look somewhat like email, as defined in [RFC821](https://tools.ietf.org/html/rfc821), [RFC2822](https://tools.ietf.org/html/rfc2822).
|
||||||
[RFC2822](https://tools.ietf.org/html/rfc2822).
|
|
||||||
|
|
||||||
The message format allows for data, metadata, and extensibility. This
|
|
||||||
combination allows the Taskserver to accommodate current and future needs. This
|
|
||||||
document describes the message format, and the supported message types.
|
|
||||||
|
|
||||||
|
The message format allows for data, metadata, and extensibility.
|
||||||
|
This combination allows the Taskserver to accommodate current and future needs.
|
||||||
|
This document describes the message format, and the supported message types.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
In this document, we adopt the convention discussed in Section 1.3.2 of
|
In this document, we adopt the convention discussed in Section 1.3.2 of [RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the significance of each particular requirement specified in this document.
|
||||||
[RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized
|
|
||||||
words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the
|
|
||||||
significance of each particular requirement specified in this document.
|
|
||||||
|
|
||||||
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute
|
|
||||||
requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there
|
|
||||||
may exist valid reasons for ignoring this item, but the full implications should
|
|
||||||
be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this
|
|
||||||
item is optional, and may be omitted without careful consideration.
|
|
||||||
|
|
||||||
|
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there may exist valid reasons for ignoring this item, but the full implications should be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this item is optional, and may be omitted without careful consideration.
|
||||||
|
|
||||||
## Encoding
|
## Encoding
|
||||||
|
|
||||||
All messages are UTF8-encoded text.
|
All messages are UTF8-encoded text.
|
||||||
|
|
||||||
|
|
||||||
## Message Format
|
## Message Format
|
||||||
|
|
||||||
This format is based on [RFC2822](https://tools.ietf.org/html/rfc2822),
|
This format is based on [RFC2822](https://tools.ietf.org/html/rfc2822), \'Internet Message Format\'.
|
||||||
\'Internet Message Format\'. Here is an example of the format:
|
Here is an example of the format:
|
||||||
|
|
||||||
<SIZE>
|
<SIZE>
|
||||||
name: value
|
name: value
|
||||||
|
@ -44,22 +32,21 @@ This format is based on [RFC2822](https://tools.ietf.org/html/rfc2822),
|
||||||
|
|
||||||
payload
|
payload
|
||||||
|
|
||||||
There are three sections. The first is the size, which is a 4-byte, big- Endian,
|
There are three sections.
|
||||||
binary byte count of the length of the message, including the 4 bytes for the
|
The first is the size, which is a 4-byte, big- Endian, binary byte count of the length of the message, including the 4 bytes for the size.
|
||||||
size.
|
|
||||||
|
|
||||||
The header section is a set of name/value pairs separated by newline characters
|
The header section is a set of name/value pairs separated by newline characters (U+000D).
|
||||||
(U+000D). The name is separated from the value by \': \' (colon U+003A, space
|
The name is separated from the value by \': \' (colon U+003A, space U+0020) The header section is terminated by two consecutive newline (U+000D) characters.
|
||||||
U+0020) The header section is terminated by two consecutive newline (U+000D)
|
All text is UTF8-encoded.
|
||||||
characters. All text is UTF8-encoded.
|
|
||||||
|
|
||||||
The payload section is arbitrary, and message type-specific. However, it is
|
The payload section is arbitrary, and message type-specific.
|
||||||
still UTF8-encoded text.
|
However, it is still UTF8-encoded text.
|
||||||
|
|
||||||
|
|
||||||
## Message Requirements
|
## Message Requirements
|
||||||
|
|
||||||
Messages SHALL contain particular headers. Those are:
|
Messages SHALL contain particular headers.
|
||||||
|
Those are:
|
||||||
|
|
||||||
- type
|
- type
|
||||||
- protocol
|
- protocol
|
||||||
|
@ -67,13 +54,11 @@ Messages SHALL contain particular headers. Those are:
|
||||||
|
|
||||||
The \'type\' value is what determines the interpretation of the payload.
|
The \'type\' value is what determines the interpretation of the payload.
|
||||||
|
|
||||||
The \'protocol\' value should be \'v1\', or any subsequently published protocol
|
The \'protocol\' value should be \'v1\', or any subsequently published protocol version.
|
||||||
version.
|
|
||||||
|
|
||||||
The \'client\' represent the client identifier, so that any special cases can be
|
The \'client\' represent the client identifier, so that any special cases can be handled.
|
||||||
handled. For example, an emergency fix that is client version-specific could be
|
For example, an emergency fix that is client version-specific could be released, to support users that have not updated their client, or perhaps the client has not released a fix.
|
||||||
released, to support users that have not updated their client, or perhaps the
|
The form of the \'version\' value is:
|
||||||
client has not released a fix. The form of the \'version\' value is:
|
|
||||||
|
|
||||||
<product identifier> <version number>
|
<product identifier> <version number>
|
||||||
|
|
||||||
|
@ -81,14 +66,13 @@ As an example:
|
||||||
|
|
||||||
taskwarrior 2.3.0
|
taskwarrior 2.3.0
|
||||||
|
|
||||||
DO NOT spoof any other software using this client value. If another client is
|
DO NOT spoof any other software using this client value.
|
||||||
spoofed, then patches addressing protocol errors may break working software.
|
If another client is spoofed, then patches addressing protocol errors may break working software.
|
||||||
|
|
||||||
|
|
||||||
## Auth Data
|
## Auth Data
|
||||||
|
|
||||||
Every request from the client SHALL contain \"auth\" information, which involves
|
Every request from the client SHALL contain \"auth\" information, which involves these header entries:
|
||||||
these header entries:
|
|
||||||
|
|
||||||
org: <organization>
|
org: <organization>
|
||||||
user: <user>
|
user: <user>
|
||||||
|
@ -96,8 +80,8 @@ these header entries:
|
||||||
|
|
||||||
The user and org fields uniquely identify a user.
|
The user and org fields uniquely identify a user.
|
||||||
|
|
||||||
The key field is generated when a new server account is set up. It is a shared
|
The key field is generated when a new server account is set up.
|
||||||
secret, equivalent to a password, and should be protected.
|
It is a shared secret, equivalent to a password, and should be protected.
|
||||||
|
|
||||||
Authentication failure can result in these errors:
|
Authentication failure can result in these errors:
|
||||||
|
|
||||||
|
@ -112,30 +96,26 @@ Every response from the Taskserver SHALL contain status data:
|
||||||
code: <code>
|
code: <code>
|
||||||
status: <status text>
|
status: <status text>
|
||||||
|
|
||||||
The code is a numeric status indicator defined in the [Sync
|
The code is a numeric status indicator defined in the [Sync Protocol](/docs/design/protocol).
|
||||||
Protocol](/docs/design/protocol).
|
|
||||||
|
|
||||||
|
|
||||||
## Payload Data
|
## Payload Data
|
||||||
|
|
||||||
Payload data is optional, arbitrary and message type dependent. It is always
|
Payload data is optional, arbitrary and message type dependent.
|
||||||
UTF8-encoded text.
|
It is always UTF8-encoded text.
|
||||||
|
|
||||||
|
|
||||||
## Message Types
|
## Message Types
|
||||||
|
|
||||||
The Taskserver supports several message types, thus providing a set of
|
The Taskserver supports several message types, thus providing a set of primitives for use by clients.
|
||||||
primitives for use by clients.
|
|
||||||
|
|
||||||
It is expected that the number of supported ticket types will increase over
|
It is expected that the number of supported ticket types will increase over time.
|
||||||
time.
|
|
||||||
|
|
||||||
|
|
||||||
## Sync Message
|
## Sync Message
|
||||||
|
|
||||||
The \"sync\" message always originates from the client, but the response will
|
The \"sync\" message always originates from the client, but the response will contain data from the server.
|
||||||
contain data from the server. A sync is therefore a single request with a single
|
A sync is therefore a single request with a single response.
|
||||||
response.
|
|
||||||
|
|
||||||
The \"sync\" message type MUST contain the following headers:
|
The \"sync\" message type MUST contain the following headers:
|
||||||
|
|
||||||
|
@ -166,9 +146,7 @@ Here is an example of a sync message:
|
||||||
2e4685f8-34bc-4f9b-b7ed-399388e182e1
|
2e4685f8-34bc-4f9b-b7ed-399388e182e1
|
||||||
{"description":"Test data","entry":"20130602T002341Z","status":"pending"}
|
{"description":"Test data","entry":"20130602T002341Z","status":"pending"}
|
||||||
|
|
||||||
The request contains the proper auth section, and the body contains the current
|
The request contains the proper auth section, and the body contains the current sync key followed by a newline characters (U+000D), then a list of JSON-formatted tasks \[2\] each separated by a newline character (U+000D).
|
||||||
sync key followed by a newline characters (U+000D), then a list of
|
|
||||||
JSON-formatted tasks \[2\] each separated by a newline character (U+000D).
|
|
||||||
|
|
||||||
An example response message might be:
|
An example response message might be:
|
||||||
|
|
||||||
|
@ -180,8 +158,7 @@ An example response message might be:
|
||||||
|
|
||||||
45da7110-1bcc-4318-d33e-12267a774e0f
|
45da7110-1bcc-4318-d33e-12267a774e0f
|
||||||
|
|
||||||
The status indicates success, and the payload contains zero remote task
|
The status indicates success, and the payload contains zero remote task modifications, followed by a sync key.
|
||||||
modifications, followed by a sync key.
|
|
||||||
|
|
||||||
|
|
||||||
## Statistics Message
|
## Statistics Message
|
||||||
|
@ -195,7 +172,8 @@ The message format іs simply:
|
||||||
client: taskd 1.0.0
|
client: taskd 1.0.0
|
||||||
protocol: v1
|
protocol: v1
|
||||||
|
|
||||||
There is no payload. An example response message might be:
|
There is no payload.
|
||||||
|
An example response message might be:
|
||||||
|
|
||||||
<size>type: response
|
<size>type: response
|
||||||
client: taskd 1.0.0
|
client: taskd 1.0.0
|
||||||
|
@ -216,6 +194,5 @@ There is no payload. An example response message might be:
|
||||||
|
|
||||||
There is no payload, and the results are in the header variables.
|
There is no payload, and the results are in the header variables.
|
||||||
|
|
||||||
Note that the statistics gathered by the server are growing, which means new
|
Note that the statistics gathered by the server are growing, which means new values are occasionally added to the response message.
|
||||||
values are occasionally added to the response message. Existing values will not
|
Existing values will not be removed.
|
||||||
be removed.
|
|
||||||
|
|
|
@ -4,16 +4,14 @@ title: "Taskwarrior - Rule System"
|
||||||
|
|
||||||
## Work in Progress
|
## Work in Progress
|
||||||
|
|
||||||
This design document is a work in progress, and subject to change. Once
|
This design document is a work in progress, and subject to change.
|
||||||
finalized, the feature will be scheduled for an upcoming release.
|
Once finalized, the feature will be scheduled for an upcoming release.
|
||||||
|
|
||||||
|
|
||||||
# Rule System
|
# Rule System
|
||||||
|
|
||||||
The rule system is a framework that supports highly configurable features, with
|
The rule system is a framework that supports highly configurable features, with runtime evaluation, DOM access and an internal API.
|
||||||
runtime evaluation, DOM access and an internal API. Implementing a rule system
|
Implementing a rule system meets the goal of shrinking and stabilizing the product core, while adding new features, and enabling many more.
|
||||||
meets the goal of shrinking and stabilizing the product core, while adding new
|
|
||||||
features, and enabling many more.
|
|
||||||
|
|
||||||
|
|
||||||
## Required Enhancements
|
## Required Enhancements
|
||||||
|
@ -60,16 +58,14 @@ To prepare for a Rules System, various subsystems must first be enhanced:
|
||||||
- The RC file will support environment variable expansion, where `${NAME}`
|
- The RC file will support environment variable expansion, where `${NAME}`
|
||||||
will be replaced by its corresponding value at launch time
|
will be replaced by its corresponding value at launch time
|
||||||
|
|
||||||
At that point, the rules system can be implemented in `libshared`, and will use
|
At that point, the rules system can be implemented in `libshared`, and will use a pluggable architecture to allow its integration into several projects.
|
||||||
a pluggable architecture to allow its integration into several projects.
|
|
||||||
|
|
||||||
|
|
||||||
## DOM Enhancements
|
## DOM Enhancements
|
||||||
|
|
||||||
DOM references will be enhanced, with many more references supported. All DOM
|
DOM references will be enhanced, with many more references supported.
|
||||||
references will begin with `dom.`, yielding unambiguous references. References
|
All DOM references will begin with `dom.`, yielding unambiguous references.
|
||||||
will have a type. Types will support sub-references (`<date>.<month>`,
|
References will have a type.
|
||||||
`<tags>.<N>`, `<annotation>.<description>`), and display formats included.
|
Types will support sub-references (`<date>.<month>`, `<tags>.<N>`, `<annotation>.<description>`), and display formats included.
|
||||||
|
|
||||||
dom . [<id> .] <attribute> [. <sub-reference>] . <format>
|
dom . [<id> .] <attribute> [. <sub-reference>] . <format>
|
||||||
|
|
||||||
|
@ -79,18 +75,15 @@ will have a type. Types will support sub-references (`<date>.<month>`,
|
||||||
dom . 123 . tags . count
|
dom . 123 . tags . count
|
||||||
dom . 123 . tags . 1
|
dom . 123 . tags . 1
|
||||||
|
|
||||||
In addition to direct attribute access, DOM references will also support tw
|
In addition to direct attribute access, DOM references will also support tw references beyond the current set: dom.rc.<name>
|
||||||
references beyond the current set:
|
|
||||||
|
|
||||||
dom.rc.<name>
|
|
||||||
dom.cli.args
|
dom.cli.args
|
||||||
dom.terminal.width
|
dom.terminal.width
|
||||||
dom.terminal.height
|
dom.terminal.height
|
||||||
dom.system.version
|
dom.system.version
|
||||||
dom.system.oѕ
|
dom.system.oѕ
|
||||||
|
|
||||||
And will also support higher-level constructs that do not directly correlate to
|
And will also support higher-level constructs that do not directly correlate to attributes, for example:
|
||||||
attributes, for example:
|
|
||||||
|
|
||||||
dom.active Boolean indicator of any active tasks
|
dom.active Boolean indicator of any active tasks
|
||||||
dom.synced Boolean indicator of the need to sync
|
dom.synced Boolean indicator of the need to sync
|
||||||
|
@ -115,34 +108,26 @@ The current configuration system supports only two different forms of syntax:
|
||||||
|
|
||||||
include <file>
|
include <file>
|
||||||
|
|
||||||
A rule is a new form of syntax that consists of the rule keyword, a name,
|
A rule is a new form of syntax that consists of the rule keyword, a name, optional trigger, followed by indented actions in the form of API calls and flow control.
|
||||||
optional trigger, followed by indented actions in the form of API calls and flow
|
For example:
|
||||||
control. For example:
|
|
||||||
|
|
||||||
rule myRule() on_launch:
|
rule myRule() on_launch:
|
||||||
# Some code here
|
# Some code here
|
||||||
|
|
||||||
A rule definition will appear in the RC file, alongside all the existing
|
A rule definition will appear in the RC file, alongside all the existing settings.
|
||||||
settings. The rule syntax will require a blank line to terminate the rule
|
The rule syntax will require a blank line to terminate the rule definition, the result being that the RC file should be quite readable, although it will look like Python.
|
||||||
definition, the result being that the RC file should be quite readable, although
|
|
||||||
it will look like Python.
|
|
||||||
|
|
||||||
|
|
||||||
## Hook Scripts
|
## Hook Scripts
|
||||||
|
|
||||||
While this functionality can also be implemented using hook scripts, rules will
|
While this functionality can also be implemented using hook scripts, rules will run in-process, and therefore do not require external interpreters to be launched every time.
|
||||||
run in-process, and therefore do not require external interpreters to be
|
This creates the potential to run faster than a hook script.
|
||||||
launched every time. This creates the potential to run faster than a hook
|
|
||||||
script.
|
|
||||||
|
|
||||||
For complex processing, hook scripts will be the preferred mechanism, but as the
|
For complex processing, hook scripts will be the preferred mechanism, but as the rules system matures, rules will be made to run more quickly.
|
||||||
rules system matures, rules will be made to run more quickly. With adequate
|
With adequate performance, a rule will be the preferred implementation over a hook script.
|
||||||
performance, a rule will be the preferred implementation over a hook script.
|
|
||||||
This is not expected to be the case at first.
|
This is not expected to be the case at first.
|
||||||
|
|
||||||
Hook scripts are not likely to be extended beyond their current form, and with
|
Hook scripts are not likely to be extended beyond their current form, and with greater DOM access and a growing API, rules should be able to supplant most hook script use cases.
|
||||||
greater DOM access and a growing API, rules should be able to supplant most hook
|
|
||||||
script use cases.
|
|
||||||
|
|
||||||
|
|
||||||
## Rule Triggers
|
## Rule Triggers
|
||||||
|
@ -150,11 +135,21 @@ script use cases.
|
||||||
The set of supported rule types will include:
|
The set of supported rule types will include:
|
||||||
|
|
||||||
* `on_launch` - Triggered on program launch.
|
* `on_launch` - Triggered on program launch.
|
||||||
* `on_add` - Triggered when a task is added. A context task will be provided. The rule can modify the task, and approve or reject it.
|
|
||||||
* `on_modify` - Triggered when a task is modified. A before and after context task will be provided. The rule can modify the task, and approve or reject it.
|
* `on_add` - Triggered when a task is added.
|
||||||
|
A context task will be provided.
|
||||||
|
The rule can modify the task, and approve or reject it.
|
||||||
|
|
||||||
|
* `on_modify` - Triggered when a task is modified.
|
||||||
|
A before and after context task will be provided.
|
||||||
|
The rule can modify the task, and approve or reject it.
|
||||||
|
|
||||||
* `on_exit` - Triggered on program exit.
|
* `on_exit` - Triggered on program exit.
|
||||||
|
|
||||||
* `color` - Triggered when colors are being determined.
|
* `color` - Triggered when colors are being determined.
|
||||||
|
|
||||||
* `virtual tag` - Defines a new virtual tag.
|
* `virtual tag` - Defines a new virtual tag.
|
||||||
|
|
||||||
* `format` - Triggered when an attribute needs formatting, defines are new format.
|
* `format` - Triggered when an attribute needs formatting, defines are new format.
|
||||||
|
|
||||||
More rules types will be added for more capabilities in future releases.
|
More rules types will be added for more capabilities in future releases.
|
||||||
|
@ -165,23 +160,37 @@ More rules types will be added for more capabilities in future releases.
|
||||||
The API is a simple set of actions that may be taken by a rule.
|
The API is a simple set of actions that may be taken by a rule.
|
||||||
|
|
||||||
* `debug(<string>)` - Displays the string in debug mode only and continues processing.
|
* `debug(<string>)` - Displays the string in debug mode only and continues processing.
|
||||||
|
|
||||||
* `warn(<string>)` - Displays the string as a warning continues processing.
|
* `warn(<string>)` - Displays the string as a warning continues processing.
|
||||||
|
|
||||||
* `error(<string>)` - Displays the string as an error and terminates processing.
|
* `error(<string>)` - Displays the string as an error and terminates processing.
|
||||||
* `exec(<binary> [ <args> ... ])` - Executes the external program and passes arguments to it. If the program exits with non-zero status, it is treated as an error.
|
|
||||||
|
* `exec(<binary> [ <args> ... ])` - Executes the external program and passes arguments to it.
|
||||||
|
If the program exits with non-zero status, it is treated as an error.
|
||||||
|
|
||||||
* `return <value>` - Provides a result value for the rule, when necessary.
|
* `return <value>` - Provides a result value for the rule, when necessary.
|
||||||
|
|
||||||
This is a very limited set at first, and more API calls will be added to support
|
This is a very limited set at first, and more API calls will be added to support capabilities in future releases.
|
||||||
capabilities in future releases.
|
|
||||||
|
|
||||||
|
|
||||||
## Grammar
|
## Grammar
|
||||||
|
|
||||||
The grammar closely tracks that of Python. Blocks are indented consistently.
|
The grammar closely tracks that of Python.
|
||||||
|
Blocks are indented consistently.
|
||||||
|
|
||||||
* `if <condition>: ... else: ... ` - The condition is a full Algebraic expression, and supports none of the command line conveniences. Terms must be combined with logical operators. The condition is an expression that is evaluated and converted to a Boolean value.
|
* `if <condition>: ... else: ...` - The condition is a full Algebraic expression, and supports none of the command line conveniences.
|
||||||
* `for <name> in <collection>: ` - There is no native type for a collection, but there are DOM references (`tags` \...) that reference collections. This provides a way to iterate.
|
Terms must be combined with logical operators.
|
||||||
* `set <name> = <expression> ` - Writes to a named type. The name may be a writable DOM object (`dom...`) or temporary variable storage (`tmp...`). Writing to a read-only DOM reference is an error.
|
The condition is an expression that is evaluated and converted to a Boolean value.
|
||||||
* `<function>([<args>]) ` - A function is either a rule or an API call. Calling an undefined function is an error.
|
|
||||||
|
* `for <name> in <collection>:` - There is no native type for a collection, but there are DOM references (`tags` \...) that reference collections.
|
||||||
|
This provides a way to iterate.
|
||||||
|
|
||||||
|
* `set <name> = <expression>` - Writes to a named type.
|
||||||
|
The name may be a writable DOM object (`dom...`) or temporary variable storage (`tmp...`).
|
||||||
|
Writing to a read-only DOM reference is an error.
|
||||||
|
|
||||||
|
* `<function>([<args>])` - A function is either a rule or an API call.
|
||||||
|
Calling an undefined function is an error.
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
|
@ -5,36 +5,28 @@ title: "Taskwarrior - Taskserver Sync Algorithm"
|
||||||
|
|
||||||
# Taskserver Sync Algorithm
|
# Taskserver Sync Algorithm
|
||||||
|
|
||||||
This document describes how task changes are merged by the Taskserver. It does
|
This document describes how task changes are merged by the Taskserver.
|
||||||
not describe [the protocol](/docs/design/protocol) used by the Taskserver.
|
It does not describe [the protocol](/docs/design/protocol) used by the Taskserver.
|
||||||
|
|
||||||
The Taskserver merges tasks from multiple sources, resulting in conflict- free
|
The Taskserver merges tasks from multiple sources, resulting in conflict- free syncing of data.
|
||||||
syncing of data. The algorithm used to achieve this is simple and effective,
|
The algorithm used to achieve this is simple and effective, paralleling what SCM systems do to perform a rebase.
|
||||||
paralleling what SCM systems do to perform a rebase.
|
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
In this document, we adopt the convention discussed in Section 1.3.2 of
|
In this document, we adopt the convention discussed in Section 1.3.2 of
|
||||||
[RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized
|
[RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the significance of each particular requirement specified in this document.
|
||||||
words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the
|
|
||||||
significance of each particular requirement specified in this document.
|
|
||||||
|
|
||||||
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute
|
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there may exist valid reasons for ignoring this item, but the full implications should be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this item is optional, and may be omitted without careful consideration.
|
||||||
requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there
|
|
||||||
may exist valid reasons for ignoring this item, but the full implications should
|
|
||||||
be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this
|
|
||||||
item is optional, and may be omitted without careful consideration.
|
|
||||||
|
|
||||||
|
|
||||||
## Problem Definition
|
## Problem Definition
|
||||||
|
|
||||||
The sync algorithm considers a single task, with multiple changes occurring in
|
The sync algorithm considers a single task, with multiple changes occurring in two separate locations that must be resolved.
|
||||||
two separate locations that must be resolved. The two locations are the local
|
The two locations are the local machine and the server.
|
||||||
machine and the server. This results in two parallel change sequences.
|
This results in two parallel change sequences.
|
||||||
|
|
||||||
Examples using multiple clients collapse down to the simple two-branch case
|
Examples using multiple clients collapse down to the simple two-branch case because the clients are merged serially.
|
||||||
because the clients are merged serially.
|
|
||||||
|
|
||||||
|
|
||||||
## Change Sequence
|
## Change Sequence
|
||||||
|
@ -43,9 +35,9 @@ A sequence of changes to the same task is represented as:
|
||||||
|
|
||||||
T0 --> T1 --> T2
|
T0 --> T1 --> T2
|
||||||
|
|
||||||
Although all examples are of the two-branch variety, some involve trivial
|
Although all examples are of the two-branch variety, some involve trivial branches.
|
||||||
branches. Going through these examples will illustrate the algorithm. First the
|
Going through these examples will illustrate the algorithm.
|
||||||
legend:
|
First the legend:
|
||||||
|
|
||||||
T0 Represents the original task, the base.
|
T0 Represents the original task, the base.
|
||||||
T1 Represents the task with a non-trivial set of changes.
|
T1 Represents the task with a non-trivial set of changes.
|
||||||
|
@ -54,9 +46,8 @@ legend:
|
||||||
|
|
||||||
## Deltas
|
## Deltas
|
||||||
|
|
||||||
The transition from T0 \--\> T1 can be seen as a transform applied to T0,
|
The transition from T0 \--\> T1 can be seen as a transform applied to T0, resulting in T1.
|
||||||
resulting in T1. That transform is the delta (d1) between T0 and T1, which is a
|
That transform is the delta (d1) between T0 and T1, which is a subtractive term:
|
||||||
subtractive term:
|
|
||||||
|
|
||||||
d1 = (T1 - T0)
|
d1 = (T1 - T0)
|
||||||
|
|
||||||
|
@ -65,9 +56,8 @@ Therefore:
|
||||||
T0 --> T1 = T0 + d1
|
T0 --> T1 = T0 + d1
|
||||||
= T0 + (T1 - T0)
|
= T0 + (T1 - T0)
|
||||||
|
|
||||||
This states that the transition from T0 to T1 is the application of a delta to
|
This states that the transition from T0 to T1 is the application of a delta to the original, T0, which results in T1.
|
||||||
the original, T0, which results in T1. Applying this to the whole change
|
Applying this to the whole change sequence yields:
|
||||||
sequence yields:
|
|
||||||
|
|
||||||
T0 --> T1 --> T2 = T0 + d1 + d2
|
T0 --> T1 --> T2 = T0 + d1 + d2
|
||||||
= T0 + (T1 - T0) + (T2 - T1)
|
= T0 + (T1 - T0) + (T2 - T1)
|
||||||
|
@ -75,34 +65,30 @@ sequence yields:
|
||||||
|
|
||||||
## Use Case Classification
|
## Use Case Classification
|
||||||
|
|
||||||
Because clients sync requests are processed serially, there is no need to
|
Because clients sync requests are processed serially, there is no need to consider the multiple client cases.
|
||||||
consider the multiple client cases. This means there is only ever the case with
|
This means there is only ever the case with two parallel change sequences = the two branch case.
|
||||||
two parallel change sequences = the two branch case.
|
|
||||||
|
|
||||||
|
|
||||||
## Two Branch Case
|
## Two Branch Case
|
||||||
|
|
||||||
The two branch case represents changes made to the same task in two locations,
|
The two branch case represents changes made to the same task in two locations, resulting in two deltas that must be applied to the same base.
|
||||||
resulting in two deltas that must be applied to the same base.
|
|
||||||
|
|
||||||
T0 --> T1
|
T0 --> T1
|
||||||
T0 --> T2
|
T0 --> T2
|
||||||
|
|
||||||
This reduces to a base with two deltas, but the order in which the deltas are
|
This reduces to a base with two deltas, but the order in which the deltas are applied is important.
|
||||||
applied is important. For example:
|
For example:
|
||||||
|
|
||||||
T0 + d1 + d2 =/= T0 + d2 + d1
|
T0 + d1 + d2 =/= T0 + d2 + d1
|
||||||
|
|
||||||
The application of deltas is not commutative, except in the trivial case where
|
The application of deltas is not commutative, except in the trivial case where the two deltas are identical, or the deltas do not overlap.
|
||||||
the two deltas are identical, or the deltas do not overlap. The deltas therefore
|
The deltas therefore need to be applied in the correct sequence.
|
||||||
need to be applied in the correct sequence. Tasks have metadata that indicates
|
Tasks have metadata that indicates the last modified time, which dictates the sequence.
|
||||||
the last modified time, which dictates the sequence. Assuming d1 occurred before
|
Assuming d1 occurred before d2, this neatly collapses down to a single branch sequence:
|
||||||
d2, this neatly collapses down to a single branch sequence:
|
|
||||||
|
|
||||||
T0 + d1 + d2 = T3
|
T0 + d1 + d2 = T3
|
||||||
|
|
||||||
Note that the result in this case is T3, because it will be neither T1 nor T2,
|
Note that the result in this case is T3, because it will be neither T1 nor T2, unless the deltas are identical.
|
||||||
unless the deltas are identical.
|
|
||||||
|
|
||||||
|
|
||||||
## Two Branch, Multiple Changes Case
|
## Two Branch, Multiple Changes Case
|
||||||
|
@ -112,8 +98,8 @@ The two branch case can be complicated by multiple changes per branch:
|
||||||
T0 --> T1 --> T3 --> T5
|
T0 --> T1 --> T3 --> T5
|
||||||
T0 --> T2 --> T4
|
T0 --> T2 --> T4
|
||||||
|
|
||||||
Note that the numbers were chosen to represent the order in which the changes
|
Note that the numbers were chosen to represent the order in which the changes were made.
|
||||||
were made. First a list of deltas is generated:
|
First a list of deltas is generated:
|
||||||
|
|
||||||
T0 --> T1 = d1
|
T0 --> T1 = d1
|
||||||
T1 --> T3 = d3
|
T1 --> T3 = d3
|
||||||
|
@ -170,8 +156,7 @@ If d1 occurred before d2, the result is:
|
||||||
|
|
||||||
## Use Cases
|
## Use Cases
|
||||||
|
|
||||||
A range of illustrated use cases, from the trivial to the complex will show the
|
A range of illustrated use cases, from the trivial to the complex will show the algorithm in use.
|
||||||
algorithm in use.
|
|
||||||
|
|
||||||
|
|
||||||
## Use Case 1: New Local Task
|
## Use Case 1: New Local Task
|
||||||
|
@ -181,7 +166,8 @@ Initial state:
|
||||||
Server: -
|
Server: -
|
||||||
Client: T0
|
Client: T0
|
||||||
|
|
||||||
The server has no data, and so T0 is stored. The result is now:
|
The server has no data, and so T0 is stored.
|
||||||
|
The result is now:
|
||||||
|
|
||||||
Server: T0
|
Server: T0
|
||||||
Client: T0
|
Client: T0
|
||||||
|
@ -199,7 +185,8 @@ The server resolves the change:
|
||||||
T0 --> T1 = T0 + d1
|
T0 --> T1 = T0 + d1
|
||||||
= T1
|
= T1
|
||||||
|
|
||||||
T1 is stored. The result is now:
|
T1 is stored.
|
||||||
|
The result is now:
|
||||||
|
|
||||||
Server: T0 --> T1
|
Server: T0 --> T1
|
||||||
Client: T1
|
Client: T1
|
||||||
|
@ -221,7 +208,8 @@ The order of change is determine to be d1, d2, yielding T3:
|
||||||
|
|
||||||
T3 = T0 + d1 + d2
|
T3 = T0 + d1 + d2
|
||||||
|
|
||||||
T3 is stored on the server, and returned to the client. The result is now:
|
T3 is stored on the server, and returned to the client.
|
||||||
|
The result is now:
|
||||||
|
|
||||||
Server: T0 --> T1 --> T2 --> T3
|
Server: T0 --> T1 --> T2 --> T3
|
||||||
Client: T3
|
Client: T3
|
||||||
|
@ -247,7 +235,8 @@ The order of change is determine to be d1, d2, d3, d4, yielding T5:
|
||||||
|
|
||||||
T5 = T0 + d1 + d2 + d3 + d4
|
T5 = T0 + d1 + d2 + d3 + d4
|
||||||
|
|
||||||
T5 is stored on the server, and returned to the client. The result is now:
|
T5 is stored on the server, and returned to the client.
|
||||||
|
The result is now:
|
||||||
|
|
||||||
Server: T0 --> T1 --> T2 --> T3 --> T4 --> T5
|
Server: T0 --> T1 --> T2 --> T3 --> T4 --> T5
|
||||||
Client: T5
|
Client: T5
|
||||||
|
|
|
@ -5,48 +5,37 @@ title: "Taskwarrior - Taskwarrior JSON Format"
|
||||||
|
|
||||||
# Taskwarrior JSON Format
|
# Taskwarrior JSON Format
|
||||||
|
|
||||||
When Taskwarrior exchanges data, it uses [JSON](https://www.json.org/). This
|
When Taskwarrior exchanges data, it uses [JSON](https://www.json.org/).
|
||||||
document describes the structure and semantics for tasks exported from
|
This document describes the structure and semantics for tasks exported from Taskwarrior, imported to Taskwarrior, or synced with the Taskserver.
|
||||||
Taskwarrior, imported to Taskwarrior, or synced with the Taskserver.
|
|
||||||
|
|
||||||
Any client of the Taskserver will need to communicate task information. This
|
Any client of the Taskserver will need to communicate task information.
|
||||||
document describes the format of a single task. It does not describe the
|
This document describes the format of a single task.
|
||||||
communication and sync protocol between client and server.
|
It does not describe the communication and sync protocol between client and server.
|
||||||
|
|
||||||
This document is subject to change. The data attributes are also subject to
|
This document is subject to change.
|
||||||
change.
|
The data attributes are also subject to change.
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
In this document, we adopt the convention discussed in Section 1.3.2 of
|
In this document, we adopt the convention discussed in Section 1.3.2 of [RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the significance of each particular requirement specified in this document.
|
||||||
[RFC1122](https://tools.ietf.org/html/rfc1122#page-16) of using the capitalized
|
|
||||||
words MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, and OPTIONAL to define the
|
|
||||||
significance of each particular requirement specified in this document.
|
|
||||||
|
|
||||||
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute
|
In brief: \"MUST\" (or \"REQUIRED\") means that the item is an absolute requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there may exist valid reasons for ignoring this item, but the full implications should be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this item is optional, and may be omitted without careful consideration.
|
||||||
requirement of the specification; \"SHOULD\" (or \"RECOMMENDED\") means there
|
|
||||||
may exist valid reasons for ignoring this item, but the full implications should
|
|
||||||
be understood before doing so; and \"MAY\" (or \"OPTIONAL\") means that this
|
|
||||||
item is optional, and may be omitted without careful consideration.
|
|
||||||
|
|
||||||
|
|
||||||
## General Format
|
## General Format
|
||||||
|
|
||||||
The format is JSON, specifically a JSON object as a single line of text,
|
The format is JSON, specifically a JSON object as a single line of text, terminated by a newline (U+000D).
|
||||||
terminated by a newline (U+000D).
|
|
||||||
|
|
||||||
The JSON looks like this:
|
The JSON looks like this:
|
||||||
|
|
||||||
{"description":"One two three","status":"pending", ... }
|
{"description":"One two three","status":"pending", ... }
|
||||||
|
|
||||||
While this is not a valid task (there are missing fields), the format is
|
While this is not a valid task (there are missing fields), the format is illustrated.
|
||||||
illustrated.
|
|
||||||
|
|
||||||
All attribute names are quoted with \" (U+0022). A name will always have a
|
All attribute names are quoted with \" (U+0022).
|
||||||
corresponding value, and if a value is blank, then the name/value pair is
|
A name will always have a corresponding value, and if a value is blank, then the name/value pair is omitted from the line.
|
||||||
omitted from the line. Newline characters are not permitted within the value,
|
Newline characters are not permitted within the value, meaning that a task consists of a single line of text.
|
||||||
meaning that a task consists of a single line of text.
|
|
||||||
|
|
||||||
All data is UTF8.
|
All data is UTF8.
|
||||||
|
|
||||||
|
@ -63,8 +52,7 @@ Strings may consist of any UTF8 encoded characters.
|
||||||
|
|
||||||
## Data Type: Fixed String
|
## Data Type: Fixed String
|
||||||
|
|
||||||
A fixed string is one value from a set of acceptable values, such as a priority
|
A fixed string is one value from a set of acceptable values, such as a priority level, where the values may only be \"\", \"L\", \"M\" or \"H\".
|
||||||
level, where the values may only be \"\", \"L\", \"M\" or \"H\".
|
|
||||||
|
|
||||||
|
|
||||||
## Data Type: UUID
|
## Data Type: UUID
|
||||||
|
@ -87,8 +75,7 @@ Integers are rendered in a simple fashion:
|
||||||
|
|
||||||
## Data Type: Date
|
## Data Type: Date
|
||||||
|
|
||||||
Dates are rendered in ISO 8601 combined date and time in UTC format using the
|
Dates are rendered in ISO 8601 combined date and time in UTC format using the template:
|
||||||
template:
|
|
||||||
|
|
||||||
YYYYMMDDTHHMMSSZ
|
YYYYMMDDTHHMMSSZ
|
||||||
|
|
||||||
|
@ -101,7 +88,8 @@ No other formats are supported.
|
||||||
|
|
||||||
## Data Type: Duration
|
## Data Type: Duration
|
||||||
|
|
||||||
Duration values represent a time period. They take the form:
|
Duration values represent a time period.
|
||||||
|
They take the form:
|
||||||
|
|
||||||
[[<sign>] <number>] <unit>
|
[[<sign>] <number>] <unit>
|
||||||
|
|
||||||
|
@ -165,11 +153,9 @@ The supported units are:
|
||||||
- yr
|
- yr
|
||||||
- y
|
- y
|
||||||
|
|
||||||
Note that some values lack precision, for example \"2q\" means two quarters, or
|
Note that some values lack precision, for example \"2q\" means two quarters, or half a year.
|
||||||
half a year.
|
|
||||||
|
|
||||||
Note that not all combinations of and make sense, for example \"3annual\" makes
|
Note that not all combinations of and make sense, for example \"3annual\" makes no sense, but evaluates to \"3years\".
|
||||||
no sense, but evaluates to \"3years\".
|
|
||||||
|
|
||||||
|
|
||||||
## The Attributes
|
## The Attributes
|
||||||
|
@ -232,59 +218,49 @@ There are other forms, which are conditional upon the state of a task:
|
||||||
|
|
||||||
(Legend: Reqd = required, Opt = optional, Intrn = Internally generated)
|
(Legend: Reqd = required, Opt = optional, Intrn = Internally generated)
|
||||||
|
|
||||||
All tasks have four required fields. There are other states in which a task may
|
All tasks have four required fields.
|
||||||
exist, and the requirements change. At a minimum, a valid task contains:
|
There are other states in which a task may exist, and the requirements change.
|
||||||
|
At a minimum, a valid task contains:
|
||||||
|
|
||||||
- uuid
|
- uuid
|
||||||
- status
|
- status
|
||||||
- entry
|
- entry
|
||||||
- description
|
- description
|
||||||
|
|
||||||
*Deleted*\
|
*Deleted* - A deleted task MUST also have \"status\":\"deleted\", an \"end\" date and a \"modified\" date.
|
||||||
A deleted task MUST also have \"status\":\"deleted\", an \"end\" date and a
|
|
||||||
\"modified\" date.
|
|
||||||
|
|
||||||
*Completed*\
|
*Completed* - A completed task MUST also have \"status\":\"completed\", an \"end\" date and a \"modified\" date.
|
||||||
A completed task MUST also have \"status\":\"completed\", an \"end\" date and a
|
|
||||||
\"modified\" date.
|
|
||||||
|
|
||||||
*Waiting*\
|
*Waiting* - A waiting task MUST also have \"status\":\"waiting\" and a \"wait\" date.
|
||||||
A waiting task MUST also have \"status\":\"waiting\" and a \"wait\" date. The
|
The task is hidden from the user, until that \"wait\" date has passed, whereupon the status reverts to \"pending\", and the \"wait\" date is removed.
|
||||||
task is hidden from the user, until that \"wait\" date has passed, whereupon the
|
|
||||||
status reverts to \"pending\", and the \"wait\" date is removed.
|
|
||||||
|
|
||||||
*Recurring Parent*\
|
*Recurring Parent* - When a recurring task is entered, it MUST have \"status\":\"recurring\", a \"recur\" period and a \"due\" date.
|
||||||
When a recurring task is entered, it MUST have \"status\":\"recurring\", a
|
It MAY also have an \"until\" date.
|
||||||
\"recur\" period and a \"due\" date. It MAY also have an \"until\" date.
|
|
||||||
Recurring parent tasks are hidden from the user.
|
Recurring parent tasks are hidden from the user.
|
||||||
|
|
||||||
*Recurring Child*\
|
*Recurring Child* - A recurring child task is not created by the user, but is cloned from the recurring parent task by the Taskserver.
|
||||||
A recurring child task is not created by the user, but is cloned from the
|
It may be modified by the user.
|
||||||
recurring parent task by the Taskserver. It may be modified by the user. On
|
On completion, there is special handling to be done.
|
||||||
completion, there is special handling to be done. See section 3.11.
|
See section 3.11.
|
||||||
|
|
||||||
|
|
||||||
## Additional Attributes
|
## Additional Attributes
|
||||||
|
|
||||||
There MAY be other fields than those listed above in a task definition. Such
|
There MAY be other fields than those listed above in a task definition.
|
||||||
fields MUST be preserved intact by any client, which means that if a task is
|
Such fields MUST be preserved intact by any client, which means that if a task is downloaded that contains an unrecognized field, that field MUST not be modified, and MUST continue to exist in the task..
|
||||||
downloaded that contains an unrecognized field, that field MUST not be modified,
|
|
||||||
and MUST continue to exist in the task..
|
|
||||||
|
|
||||||
User Defined Attributes (UDAs) are additional fields.
|
User Defined Attributes (UDAs) are additional fields.
|
||||||
|
|
||||||
|
|
||||||
## Attribute Details
|
## Attribute Details
|
||||||
|
|
||||||
The individual fields convey important information about a task, and in some
|
The individual fields convey important information about a task, and in some cases work only in collusion with other fields.
|
||||||
cases work only in collusion with other fields. All such details are listed
|
All such details are listed here.
|
||||||
here.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: status
|
## Attribute: status
|
||||||
|
|
||||||
The status field describes the state of the task, which may ONLY be one of these
|
The status field describes the state of the task, which may ONLY be one of these literal strings:
|
||||||
literal strings:
|
|
||||||
|
|
||||||
"status":"pending"
|
"status":"pending"
|
||||||
"status":"deleted"
|
"status":"deleted"
|
||||||
|
@ -292,35 +268,28 @@ literal strings:
|
||||||
"status":"waiting"
|
"status":"waiting"
|
||||||
"status":"recurring"
|
"status":"recurring"
|
||||||
|
|
||||||
A pending task is a task that has not yet been completed or deleted. This is the
|
A pending task is a task that has not yet been completed or deleted.
|
||||||
typical state for a task.
|
This is the typical state for a task.
|
||||||
|
|
||||||
A deleted task is one that has been removed from the pending state, and MUST
|
A deleted task is one that has been removed from the pending state, and MUST have an \"end\" field specified.
|
||||||
have an \"end\" field specified. Given the required \"entry\" and \"end\" field,
|
Given the required \"entry\" and \"end\" field, it can be determined how long the task was pending.
|
||||||
it can be determined how long the task was pending.
|
|
||||||
|
|
||||||
A completed task is one that has been removed from the pending state by
|
A completed task is one that has been removed from the pending state by completion, and MUST have an \"end\" field specified.
|
||||||
completion, and MUST have an \"end\" field specified. Given the required
|
Given the required \"entry\" and \"end\" fields, it can be determine how long the task was pending.
|
||||||
\"entry\" and \"end\" fields, it can be determine how long the task was pending.
|
|
||||||
|
|
||||||
A waiting task is ostensibly a pending task that has been hidden from typical
|
A waiting task is ostensibly a pending task that has been hidden from typical view, and MUST have a \"wait\" field containing the date when the task is automatically returned to the pending state.
|
||||||
view, and MUST have a \"wait\" field containing the date when the task is
|
If a client sees a task that is in the waiting state, and the \"wait\" field is earlier than the current date and time, the client MUST remove the \"wait\" field and set the \"status\" field to \"pending\".
|
||||||
automatically returned to the pending state. If a client sees a task that is in
|
|
||||||
the waiting state, and the \"wait\" field is earlier than the current date and
|
|
||||||
time, the client MUST remove the \"wait\" field and set the \"status\" field to
|
|
||||||
\"pending\".
|
|
||||||
|
|
||||||
A recurring task is essentially a parent template task from which child tasks
|
A recurring task is essentially a parent template task from which child tasks are cloned.
|
||||||
are cloned. The parent remains hidden from view, and contains a \"mask\" field
|
The parent remains hidden from view, and contains a \"mask\" field that represents the recurrences.
|
||||||
that represents the recurrences. Each cloned child task has an \"imask\" field
|
Each cloned child task has an \"imask\" field that indexes into the parent \"mask\" field, as well as a \"parent\" field that lists the UUID of the parent.
|
||||||
that indexes into the parent \"mask\" field, as well as a \"parent\" field that
|
|
||||||
lists the UUID of the parent.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: uuid
|
## Attribute: uuid
|
||||||
|
|
||||||
When a task is created, it MUST be assigned a new UUID by the client. Once
|
When a task is created, it MUST be assigned a new UUID by the client.
|
||||||
assigned, a UUID field MUST NOT be modified. UUID fields are permanent.
|
Once assigned, a UUID field MUST NOT be modified.
|
||||||
|
UUID fields are permanent.
|
||||||
|
|
||||||
|
|
||||||
## Attribute: entry
|
## Attribute: entry
|
||||||
|
@ -331,70 +300,61 @@ This is the creation date of the task.
|
||||||
|
|
||||||
## Attribute: description
|
## Attribute: description
|
||||||
|
|
||||||
When a task is created, it MUST have a \"description\" field value, which
|
When a task is created, it MUST have a \"description\" field value, which contains UTF8 characters.
|
||||||
contains UTF8 characters. A \"description\" field may not contain newline
|
A \"description\" field may not contain newline characters, but may contain other characters, properly escaped.
|
||||||
characters, but may contain other characters, properly escaped. See
|
See <https://json.org> for details.
|
||||||
<https://json.org> for details.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: start
|
## Attribute: start
|
||||||
|
|
||||||
To indicate that a task is being worked on, it MAY be assigned a \"start\"
|
To indicate that a task is being worked on, it MAY be assigned a \"start\" field.
|
||||||
field. Such a task is then considered Active.
|
Such a task is then considered Active.
|
||||||
|
|
||||||
|
|
||||||
## Attribute: end
|
## Attribute: end
|
||||||
|
|
||||||
When a task is deleted or completed, is MUST be assigned an \"end\" field. It is
|
When a task is deleted or completed, is MUST be assigned an \"end\" field.
|
||||||
not valid for a task to have an \"end\" field unless the status is also
|
It is not valid for a task to have an \"end\" field unless the status is also \"completed\" or \"deleted\".
|
||||||
\"completed\" or \"deleted\". If a completed task is restored to the \"pending\"
|
If a completed task is restored to the \"pending\" state, the \"end\" field is removed.
|
||||||
state, the \"end\" field is removed.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: due
|
## Attribute: due
|
||||||
|
|
||||||
A task MAY have a \"due\" field, which indicates when the task should be
|
A task MAY have a \"due\" field, which indicates when the task should be completed.
|
||||||
completed.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: until
|
## Attribute: until
|
||||||
|
|
||||||
A recurring task MAY have an \"until\" field, which is the date after which no
|
A recurring task MAY have an \"until\" field, which is the date after which no more recurring tasks should be generated.
|
||||||
more recurring tasks should be generated. At that time, the parent recurring
|
At that time, the parent recurring task is set to \"completed\".
|
||||||
task is set to \"completed\".
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: wait
|
## Attribute: wait
|
||||||
|
|
||||||
A task MAY have a \"wait\" field date, in conjunction with a \"status\" of
|
A task MAY have a \"wait\" field date, in conjunction with a \"status\" of \"waiting\".
|
||||||
\"waiting\". A waiting task is one that is not typically shown on reports until
|
A waiting task is one that is not typically shown on reports until it is past the wait date.
|
||||||
it is past the wait date.
|
|
||||||
|
|
||||||
An example of this is a birthday reminder. A task may be entered for a birthday
|
An example of this is a birthday reminder.
|
||||||
reminder in 10 months time, but can have a \"wait\" date 9 months from now,
|
A task may be entered for a birthday reminder in 10 months time, but can have a \"wait\" date 9 months from now, which means the task remains hidden until 1 month before the due date.
|
||||||
which means the task remains hidden until 1 month before the due date. This
|
This prevents long-term tasks from cluttering reports until they become relevant.
|
||||||
prevents long-term tasks from cluttering reports until they become relevant.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: recur
|
## Attribute: recur
|
||||||
|
|
||||||
The \"recur\" field is for recurring tasks, and specifies the period between
|
The \"recur\" field is for recurring tasks, and specifies the period between child tasks, in the form of a duration value.
|
||||||
child tasks, in the form of a duration value. The value is kept in the raw state
|
The value is kept in the raw state (such as \"3wks\") as a string, so that it may be evaluated each time it is needed.
|
||||||
(such as \"3wks\") as a string, so that it may be evaluated each time it is
|
|
||||||
needed.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: mask
|
## Attribute: mask
|
||||||
|
|
||||||
A parent recurring task has a \"mask\" field that is an array of child status
|
A parent recurring task has a \"mask\" field that is an array of child status indicators.
|
||||||
indicators. Suppose a task is created that is due every week for a month. The
|
Suppose a task is created that is due every week for a month.
|
||||||
\"mask\" field will look like:
|
The \"mask\" field will look like:
|
||||||
|
|
||||||
"----"
|
"----"
|
||||||
|
|
||||||
This mask has four slots, indicating that there are four child tasks, and each
|
This mask has four slots, indicating that there are four child tasks, and each slot indicates, in this case, that the child tasks are pending (\"-\").
|
||||||
slot indicates, in this case, that the child tasks are pending (\"-\"). The
|
The possible slot indicators are:
|
||||||
possible slot indicators are:
|
|
||||||
|
|
||||||
* `-` - Pending
|
* `-` - Pending
|
||||||
* `+` - Completed
|
* `+` - Completed
|
||||||
|
@ -409,34 +369,30 @@ If there were only three indicators in the mask:
|
||||||
|
|
||||||
"+-+"
|
"+-+"
|
||||||
|
|
||||||
This would indicate that the second task is pending, the first and third are
|
This would indicate that the second task is pending, the first and third are complete, and the fourth has not yet been generated.
|
||||||
complete, and the fourth has not yet been generated.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: imask
|
## Attribute: imask
|
||||||
|
|
||||||
Child recurring tasks have an \"imask\" field instead of a \"mask\" field like
|
Child recurring tasks have an \"imask\" field instead of a \"mask\" field like their parent.
|
||||||
their parent. The \"imask\" field is a zero-based integer offset into the
|
The \"imask\" field is a zero-based integer offset into the \"mask\" field of the parent.
|
||||||
\"mask\" field of the parent.
|
|
||||||
|
|
||||||
If a child task is completed, one of the changes that MUST occur is to look up
|
If a child task is completed, one of the changes that MUST occur is to look up the parent task, and using \"imask\" set the \"mask\" of the parent to the correct indicator.
|
||||||
the parent task, and using \"imask\" set the \"mask\" of the parent to the
|
This prevents recurring tasks from being generated twice.
|
||||||
correct indicator. This prevents recurring tasks from being generated twice.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: parent
|
## Attribute: parent
|
||||||
|
|
||||||
A recurring task instance MUST have a \"parent\" field, which is the UUID of the
|
A recurring task instance MUST have a \"parent\" field, which is the UUID of the task that has \"status\" of \"recurring\".
|
||||||
task that has \"status\" of \"recurring\". This linkage between tasks,
|
This linkage between tasks, established using \"parent\", \"mask\" and \"imask\" is used to track the need to generate more recurring tasks.
|
||||||
established using \"parent\", \"mask\" and \"imask\" is used to track the need
|
|
||||||
to generate more recurring tasks.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: annotation\_\...
|
## Attribute: annotation\_\...
|
||||||
|
|
||||||
Annotations are strings with timestamps. Each annotation itself has an \"entry\"
|
Annotations are strings with timestamps.
|
||||||
field and a \"description\" field, similar to the task itself. Annotations form
|
Each annotation itself has an \"entry\" field and a \"description\" field, similar to the task itself.
|
||||||
an array named \"annotations\". For example (lines broken for clarity):
|
Annotations form an array named \"annotations\".
|
||||||
|
For example (lines broken for clarity):
|
||||||
|
|
||||||
"annotations":[
|
"annotations":[
|
||||||
{"entry":"20120110T234212Z","description":"Remember to get the mail"},
|
{"entry":"20120110T234212Z","description":"Remember to get the mail"},
|
||||||
|
@ -446,12 +402,12 @@ an array named \"annotations\". For example (lines broken for clarity):
|
||||||
|
|
||||||
## Attribute: project
|
## Attribute: project
|
||||||
|
|
||||||
A project is a single string. For example:
|
A project is a single string.
|
||||||
|
For example:
|
||||||
|
|
||||||
"project":"Personal Taxes"
|
"project":"Personal Taxes"
|
||||||
|
|
||||||
Note that projects receive special handling, so that when a \".\" (U+002E) is
|
Note that projects receive special handling, so that when a \".\" (U+002E) is used, it implies a hierarchy, which means the following two projects:
|
||||||
used, it implies a hierarchy, which means the following two projects:
|
|
||||||
|
|
||||||
"Home.Kitchen"
|
"Home.Kitchen"
|
||||||
"Home.Garden"
|
"Home.Garden"
|
||||||
|
@ -461,8 +417,8 @@ are both considered part of the \"Home\" project.
|
||||||
|
|
||||||
## Attribute: tags
|
## Attribute: tags
|
||||||
|
|
||||||
The \"tags\" field is an array of string, where each string is a single word
|
The \"tags\" field is an array of string, where each string is a single word containing no spaces.
|
||||||
containing no spaces. For example:
|
For example:
|
||||||
|
|
||||||
"tags":["home","garden"]
|
"tags":["home","garden"]
|
||||||
|
|
||||||
|
@ -475,43 +431,39 @@ The \"priority\" field, if present, MAY contain one of the following strings:
|
||||||
"priority":"M"
|
"priority":"M"
|
||||||
"priority":"L"
|
"priority":"L"
|
||||||
|
|
||||||
These represent High, Medium and Low priorities. An absent priority field
|
These represent High, Medium and Low priorities.
|
||||||
indicates no priority.
|
An absent priority field indicates no priority.
|
||||||
|
|
||||||
|
|
||||||
## Attribute: depends
|
## Attribute: depends
|
||||||
|
|
||||||
The \"depends\" field is a string containing a comma-separated unique set of
|
The \"depends\" field is a string containing a comma-separated unique set of UUIDs.
|
||||||
UUIDs. If task 2 depends on task 1, then it is task 1 that must be completed
|
If task 2 depends on task 1, then it is task 1 that must be completed first.
|
||||||
first. Task 1 is considered a \"blocking\" tasks, and task 2 is considered a
|
Task 1 is considered a \"blocking\" tasks, and task 2 is considered a \"blocked\" task.
|
||||||
\"blocked\" task. For example:
|
For example:
|
||||||
|
|
||||||
"depends":",, ..."
|
"depends":",, ..."
|
||||||
|
|
||||||
Note that in a future version of this specification, this will be changed to a
|
Note that in a future version of this specification, this will be changed to a JSON array of strings, like the \"tags\" field.
|
||||||
JSON array of strings, like the \"tags\" field.
|
|
||||||
|
|
||||||
|
|
||||||
## Attribute: modified
|
## Attribute: modified
|
||||||
|
|
||||||
A task MUST have a \"modified\" field set if it is modified. This field is of
|
A task MUST have a \"modified\" field set if it is modified.
|
||||||
type \"date\", and is used as a reference when merging tasks.
|
This field is of type \"date\", and is used as a reference when merging tasks.
|
||||||
|
|
||||||
|
|
||||||
## Attribute: scheduled
|
## Attribute: scheduled
|
||||||
|
|
||||||
A task MAY have a \"scheduled\" field, which indicates when the task should be
|
A task MAY have a \"scheduled\" field, which indicates when the task should be available to start.
|
||||||
available to start. A task that has passed its \"scheduled\" data is said to be
|
A task that has passed its \"scheduled\" data is said to be \"ready\".
|
||||||
\"ready\".
|
|
||||||
|
|
||||||
|
|
||||||
## User Defined Attributes
|
## User Defined Attributes
|
||||||
|
|
||||||
A User Defined Attribute (UDA) is a field that is defined via configuration.
|
A User Defined Attribute (UDA) is a field that is defined via configuration.
|
||||||
Given that the configuration is not present in the JSON format of a task, any
|
Given that the configuration is not present in the JSON format of a task, any fields that are not recognized are to be treated as UDAs.
|
||||||
fields that are not recognized are to be treated as UDAs. This means that if a
|
This means that if a task contains a UDA, unless the meaning of it is understood, it MUST be preserved.
|
||||||
task contains a UDA, unless the meaning of it is understood, it MUST be
|
|
||||||
preserved.
|
|
||||||
|
|
||||||
UDAs may have one of four types: string, numeric, date and duration.
|
UDAs may have one of four types: string, numeric, date and duration.
|
||||||
|
|
||||||
|
|
|
@ -4,32 +4,26 @@ title: "Taskwarrior - Work Week Support"
|
||||||
|
|
||||||
## Work in Progress
|
## Work in Progress
|
||||||
|
|
||||||
This design document is a work in progress, and subject to change. Once
|
This design document is a work in progress, and subject to change.
|
||||||
finalized, the feature will be scheduled for an upcoming release.
|
Once finalized, the feature will be scheduled for an upcoming release.
|
||||||
|
|
||||||
|
|
||||||
# Work Week Support
|
# Work Week Support
|
||||||
|
|
||||||
Taskwarrior supports the idea that a week starts on either a Sunday or a Monday,
|
Taskwarrior supports the idea that a week starts on either a Sunday or a Monday, as determined by configuration.
|
||||||
as determined by configuration. This was added eight years ago, simply for
|
This was added eight years ago, simply for display purposes in the `calendar` report.
|
||||||
display purposes in the `calendar` report. Since then its use has propagated and
|
Since then its use has propagated and it influences the `sow` date reference.0
|
||||||
it influences the `sow` date reference.0
|
|
||||||
|
|
||||||
Further requests have been made to make this more flexible, so that the notion
|
Further requests have been made to make this more flexible, so that the notion of \'weekend\' can be defined.
|
||||||
of \'weekend\' can be defined. Furthermore, the idea that every week has a
|
Furthermore, the idea that every week has a weekend has also been questioned.
|
||||||
weekend has also been questioned.
|
|
||||||
|
|
||||||
It has become clear that a `weekstart` setting, and the notion of a weekend are
|
|
||||||
no longer useful.
|
|
||||||
|
|
||||||
|
It has become clear that a `weekstart` setting, and the notion of a weekend are no longer useful.
|
||||||
|
|
||||||
## Proposed Support
|
## Proposed Support
|
||||||
|
|
||||||
One option is to allow the user to completely define a work week in the
|
One option is to allow the user to completely define a work week in the following way:
|
||||||
following way:
|
|
||||||
|
|
||||||
workweek=1,2,3,4,5
|
workweek=1,2,3,4,5
|
||||||
|
|
||||||
With Sunday as day zero, this states that the work week is the typical Monday -
|
With Sunday as day zero, this states that the work week is the typical Monday - Friday.
|
||||||
Friday. From this setting, the meaning of `soww` and `eoww` can be determined,
|
From this setting, the meaning of `soww` and `eoww` can be determined, as well as `recur:weekday`.
|
||||||
as well as `recur:weekday`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue