mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Compare commits
No commits in common. "develop" and "v3.3.0" have entirely different histories.
136 changed files with 933 additions and 2172 deletions
|
@ -1 +0,0 @@
|
|||
target
|
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
|
@ -5,11 +5,6 @@ updates:
|
|||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
# Enable version updates for git submodules
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
# Enable updates for Rust packages
|
||||
- package-ecosystem: "cargo"
|
||||
directory: "/" # Location of package manifests
|
||||
|
|
38
.github/workflows/checks.yml
vendored
38
.github/workflows/checks.yml
vendored
|
@ -15,25 +15,25 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
id: toolchain
|
||||
with:
|
||||
# If this version is old enough to cause errors, or older than the
|
||||
# TaskChampion MSRV, bump it to the MSRV of the currently-required
|
||||
# TaskChampion package; if necessary, bump that version as well.
|
||||
toolchain: "1.81.0" # MSRV
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Cache cargo build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: target
|
||||
key: ${{ runner.os }}-cargo-build-target-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
# If this version is old enough to cause errors, or older than the
|
||||
# TaskChampion MSRV, bump it to the MSRV of the currently-required
|
||||
# TaskChampion package; if necessary, bump that version as well.
|
||||
toolchain: "1.78.0" # MSRV
|
||||
override: true
|
||||
|
||||
- uses: actions-rs/cargo@v1.0.3
|
||||
with:
|
||||
|
@ -53,11 +53,12 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
id: toolchain
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable"
|
||||
components: "rustfmt"
|
||||
profile: minimal
|
||||
components: rustfmt
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- uses: actions-rs/cargo@v1.0.3
|
||||
with:
|
||||
|
@ -70,11 +71,12 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
id: toolchain
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable"
|
||||
components: "rustfmt"
|
||||
profile: minimal
|
||||
components: rustfmt
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: "Check metadata"
|
||||
run: ".github/workflows/metadata-check.sh"
|
||||
|
|
6
.github/workflows/docker-image.yaml
vendored
6
.github/workflows/docker-image.yaml
vendored
|
@ -33,10 +33,10 @@ jobs:
|
|||
submodules: "recursive"
|
||||
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@v3.9.0
|
||||
uses: sigstore/cosign-installer@v3.7.0
|
||||
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
uses: docker/login-action@v3.4.0
|
||||
uses: docker/login-action@v3.3.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.repository_owner }}
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
|
||||
- name: Build and push Taskwarrior Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v6.18.0
|
||||
uses: docker/build-push-action@v6.10.0
|
||||
with:
|
||||
context: .
|
||||
file: "./docker/task.dockerfile"
|
||||
|
|
10
.github/workflows/release-check.yaml
vendored
10
.github/workflows/release-check.yaml
vendored
|
@ -6,14 +6,16 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
id: toolchain
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable"
|
||||
override: true
|
||||
|
||||
- name: Install uuid-dev
|
||||
run: sudo apt install uuid-dev
|
||||
|
|
45
.github/workflows/tests.yaml
vendored
45
.github/workflows/tests.yaml
vendored
|
@ -43,20 +43,22 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
id: toolchain
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-stable-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Cache cargo build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: target
|
||||
key: ${{ runner.os }}-cargo-build-target-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-stable-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable"
|
||||
override: true
|
||||
|
||||
- name: Test MacOS
|
||||
run: bash test/scripts/test_macos.sh
|
||||
|
@ -70,20 +72,22 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
id: toolchain
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-stable-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Cache cargo build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: target
|
||||
key: ${{ runner.os }}-cargo-build-target-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-stable-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable"
|
||||
override: true
|
||||
|
||||
- name: Test MacOS
|
||||
run: bash test/scripts/test_macos.sh
|
||||
|
@ -97,25 +101,26 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
id: toolchain
|
||||
with:
|
||||
# If this version is old enough to cause errors, or older than the
|
||||
# TaskChampion MSRV, bump it to the MSRV of the currently-required
|
||||
# TaskChampion package; if necessary, bump that version as well.
|
||||
toolchain: "1.81.0" # MSRV
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Cache cargo build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: target
|
||||
key: ${{ runner.os }}-cargo-build-target-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
# If this version is old enough to cause errors, or older than the
|
||||
# TaskChampion MSRV, bump it to the MSRV of the currently-required
|
||||
# TaskChampion package; if necessary, bump that version as well.
|
||||
# This should match the MSRV in `src/taskchampion-cpp/Cargo.toml`.
|
||||
toolchain: "1.78.0" # MSRV
|
||||
override: true
|
||||
|
||||
- uses: actions-rs/cargo@v1.0.3
|
||||
with:
|
||||
|
|
|
@ -9,11 +9,11 @@ repos:
|
|||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v20.1.6
|
||||
rev: v19.1.5
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c++, c]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 25.1.0
|
||||
rev: 24.10.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
|
|
@ -4,7 +4,7 @@ enable_testing()
|
|||
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
project (task
|
||||
VERSION 3.4.1
|
||||
VERSION 3.3.0
|
||||
DESCRIPTION "Taskwarrior - a command-line TODO list manager"
|
||||
HOMEPAGE_URL https://taskwarrior.org/)
|
||||
|
||||
|
@ -37,7 +37,7 @@ endif (EXISTS ${CMAKE_SOURCE_DIR}/src/libshared/src AND EXISTS ${CMAKE_SOURCE_DI
|
|||
message ("-- Looking for SHA1 references")
|
||||
if (EXISTS ${CMAKE_SOURCE_DIR}/.git/index)
|
||||
set (HAVE_COMMIT true)
|
||||
execute_process (COMMAND git log -1 --pretty=format:%h --no-show-signature
|
||||
execute_process (COMMAND git log -1 --pretty=format:%h
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE COMMIT)
|
||||
configure_file ( ${CMAKE_SOURCE_DIR}/commit.h.in
|
||||
|
@ -67,6 +67,7 @@ SET (TASK_BINDIR bin CACHE STRING "Installation directory for the bi
|
|||
# rust libs require these
|
||||
set (TASK_LIBRARIES dl pthread)
|
||||
|
||||
check_function_exists (timegm HAVE_TIMEGM)
|
||||
check_function_exists (get_current_dir_name HAVE_GET_CURRENT_DIR_NAME)
|
||||
check_function_exists (wordexp HAVE_WORDEXP)
|
||||
|
||||
|
@ -161,6 +162,6 @@ endforeach (doc_FILE)
|
|||
|
||||
set (CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set (CPACK_SOURCE_PACKAGE_FILE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION})
|
||||
set (CPACK_SOURCE_IGNORE_FILES "build" "target" "test" "misc/*" "performance" "swp$" "src/lex$" "task-.*.tar.gz"
|
||||
set (CPACK_SOURCE_IGNORE_FILES "build" "test" "misc/*" "performance" "swp$" "src/lex$" "task-.*.tar.gz"
|
||||
"commit.h" "cmake.h$" "\\\\.gitmodules" "src/libshared/\\\\.git" ".github/" ".*\\\\.gitignore$" "docker-compose.yml" "\\\\.git/")
|
||||
include (CPack)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
doc/devel/contrib/development.md
|
1151
Cargo.lock
generated
1151
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
31
ChangeLog
31
ChangeLog
|
@ -1,36 +1,11 @@
|
|||
------ current release ---------------------------
|
||||
|
||||
3.4.1 -
|
||||
|
||||
- The nagging to read `task news` has been fixed.
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
3.4.0 -
|
||||
|
||||
- Where possible, the task DB is now opened in read-only mode, which improves
|
||||
performance. This is the case for reports (task lists) only when the `gc`
|
||||
config is false.
|
||||
- An updated version of corrosion fixes build errors trying to find the Rust
|
||||
toolchain.
|
||||
|
||||
Thanks to the following people for contributions to this release:
|
||||
|
||||
- Dustin J. Mitchell
|
||||
- Kalle Kietäväinen
|
||||
- Karl
|
||||
- Matthew
|
||||
- Tejada-Omar
|
||||
- Tobias Predel
|
||||
- Yong Li
|
||||
- jrmarino
|
||||
|
||||
3.3.0 -
|
||||
|
||||
- Sync now supports AWS S3 as a backend.
|
||||
- A new `task import-v2` command allows importing Taskwarrior-2.x
|
||||
data files directly.
|
||||
|
||||
3.3.0 -
|
||||
|
||||
Thanks to the following people for contributions to this release:
|
||||
|
||||
- Chongyun Lee
|
||||
|
@ -43,6 +18,8 @@ Thanks to the following people for contributions to this release:
|
|||
- Scott Mcdermott
|
||||
- Thomas Lauf
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
3.2.0 -
|
||||
|
||||
- Support for the journal in `task info` has been restored (#3671) and the
|
||||
|
|
53
INSTALL
53
INSTALL
|
@ -22,7 +22,7 @@ You will need the following libraries:
|
|||
- libuuid (not needed for OSX)
|
||||
|
||||
You will need a Rust toolchain of the Minimum Supported Rust Version (MSRV):
|
||||
- rust 1.81.0
|
||||
- rust 1.78.0
|
||||
|
||||
Basic Installation
|
||||
------------------
|
||||
|
@ -34,7 +34,7 @@ Briefly, these shell commands will unpack, build and install Taskwarrior:
|
|||
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release . [3]
|
||||
$ cmake --build build [4]
|
||||
$ sudo cmake --install build [5]
|
||||
$ cd .. ; rm -r task-X.Y.Z [6] (see: Uninstallation)
|
||||
$ cd .. ; rm -r task-X.Y.Z [6]
|
||||
|
||||
These commands are explained below:
|
||||
|
||||
|
@ -89,11 +89,6 @@ get absolute installation directories:
|
|||
CMAKE_INSTALL_PREFIX/TASK_MAN1DIR /usr/local/share/man/man1
|
||||
CMAKE_INSTALL_PREFIX/TASK_MAN5DIR /usr/local/share/man/man5
|
||||
|
||||
The following variables control aspects of the build process:
|
||||
|
||||
SYSTEM_CORROSION - Use system provided corrosion instead of vendored version
|
||||
ENABLE_TLS_NATIVE_ROOTS - Use the system's TLS root certificates
|
||||
|
||||
|
||||
Uninstallation
|
||||
--------------
|
||||
|
@ -103,13 +98,6 @@ There is no uninstall option in CMake makefiles. This is a manual process.
|
|||
To uninstall Taskwarrior, remove the files listed in the install_manifest.txt
|
||||
file that was generated when you built Taskwarrior.
|
||||
|
||||
```sh
|
||||
cd task-X.Y.Z
|
||||
sudo xargs rm < build/install_manifest.txt
|
||||
```
|
||||
|
||||
If you want to uninstall this way, you will need to omit step [6] above and
|
||||
retain the source folder after installation.
|
||||
|
||||
Taskwarrior Build Notes
|
||||
-----------------------
|
||||
|
@ -122,43 +110,6 @@ If Taskwarrior will not build on your system, first take a look at the Operating
|
|||
System notes below. If this doesn't help, then go to the Troubleshooting
|
||||
section, which includes instructions on how to contact us for help.
|
||||
|
||||
Offline Build Notes
|
||||
-------------------
|
||||
|
||||
It is common for packaging systems (e.g. NixOS, FreeBSD Ports Collection, pkgsrc, etc)
|
||||
to disable networking during builds. This restriction requires all distribution files
|
||||
to be prepositioned after checksum verification as a prerequisite for the build. The
|
||||
following steps have been successful in allowing Taskwarrior to be built in this
|
||||
environment:
|
||||
|
||||
1. Extract all crates in a known location, e.g. ${WRKDIR}/cargo-crates
|
||||
This includes crates needed for corrosion (search for Cargo.lock files)
|
||||
|
||||
2. Create .cargo-checksum.json for each crate
|
||||
For example:
|
||||
printf '{"package":"%s","files":{}}' $(sha256 -q ${DISTDIR}/rayon-core-1.12.1.tar.gz) \
|
||||
> ${WRKDIR}/cargo-crates/rayon-core-1.12.1/.cargo-checksum.json
|
||||
|
||||
3. Create a custom config.toml file
|
||||
For example, ${WRKDIR}/.cargo/config.toml
|
||||
[source.cargo]
|
||||
directory = '${WRKDIR}/cargo-crates'
|
||||
[source.crates-io]
|
||||
replace-with = 'cargo'
|
||||
|
||||
4. After running cmake, configure cargo
|
||||
For example:
|
||||
cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${CARGO_ENV} \
|
||||
/usr/local/bin/cargo update \
|
||||
--manifest-path ${WRKDIR}/.cargo/config.toml \
|
||||
--verbose
|
||||
|
||||
5. Set CARGO_HOME in environment
|
||||
For example
|
||||
CARGO_HOME=${WRKDIR}/.cargo
|
||||
|
||||
The build and installation steps should be the same as a standard build
|
||||
at this point.
|
||||
|
||||
Operating System Notes
|
||||
----------------------
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
doc/devel/contrib/releasing.md
|
|
@ -41,6 +41,9 @@
|
|||
/* Found tm_gmtoff */
|
||||
#cmakedefine HAVE_TM_GMTOFF
|
||||
|
||||
/* Found timegm */
|
||||
#cmakedefine HAVE_TIMEGM
|
||||
|
||||
/* Found st.st_birthtime struct member */
|
||||
#cmakedefine HAVE_ST_BIRTHTIME
|
||||
|
||||
|
|
|
@ -24,6 +24,3 @@ To release Taskwarrior, follow this process:
|
|||
- Add a new item in `content/news`
|
||||
- Update `data/projects.json` with the latest version and a fake next version for "devel"
|
||||
- Update `data/releases.json` with the new version, and copy the tarball into `content/download`.
|
||||
- Update various things, in a new PR:
|
||||
- `cargo update`
|
||||
- `git submodule update --remote --merge`
|
||||
|
|
|
@ -25,7 +25,7 @@ In brief: "MUST" (or "REQUIRED") means that the item is an absolute requirement
|
|||
|
||||
## General Format
|
||||
|
||||
The format is JSON, specifically a JSON object as a single line of text, terminated by a line feed (U+000A).
|
||||
The format is JSON, specifically a JSON object as a single line of text, terminated by a newline (U+000D).
|
||||
|
||||
The JSON looks like this:
|
||||
|
||||
|
|
|
@ -143,9 +143,7 @@ Then configure Taskwarrior with:
|
|||
|
||||
To synchronize your tasks to AWS, select a region near you and use the AWS
|
||||
console to create a new S3 bucket. The default settings for the bucket are
|
||||
adequate. In particular, ensure that no lifecycle policies are enabled, as they
|
||||
may automatically delete or transition objects, potentially impacting data
|
||||
availability.
|
||||
adequate.
|
||||
|
||||
You will also need an AWS IAM user with the following policy, where BUCKETNAME
|
||||
is the name of the bucket. The same user can be configured for multiple
|
||||
|
|
|
@ -1037,7 +1037,7 @@ modifier requires that the attribute contain the whole word specified, such
|
|||
that this:
|
||||
|
||||
.nf
|
||||
task description.word:foo list
|
||||
task description.word:bar list
|
||||
.fi
|
||||
|
||||
Will match the description 'foo bar baz' but does not match 'dog food'.
|
||||
|
|
|
@ -212,9 +212,6 @@ This is a path to the hook scripts directory. By default it is ~/.task/hooks.
|
|||
.TP
|
||||
.B gc=1
|
||||
Can be used to temporarily suspend rebuilding, so that task IDs don't change.
|
||||
Rebuilding requires read/write access to the database, so disabling `gc` may
|
||||
result in better performance.
|
||||
|
||||
Note that this should be used in the form of a command line override (task
|
||||
rc.gc=0 ...), and not permanently used in the .taskrc file, as this
|
||||
significantly affects performance in the long term.
|
||||
|
@ -1384,7 +1381,7 @@ if you define a UDA named 'estimate', Taskwarrior will not know that this value
|
|||
is weeks, hours, minutes, money, or some other resource count.
|
||||
|
||||
.TP
|
||||
.B uda.<name>.type=string|numeric|uuid|date|duration
|
||||
.B uda.<name>.type=string|numeric|date|duration
|
||||
.RS
|
||||
Defines a UDA called '<name>', of the specified type.
|
||||
.RE
|
||||
|
|
|
@ -6,20 +6,20 @@ include_directories (${CMAKE_SOURCE_DIR}
|
|||
${CMAKE_SOURCE_DIR}/src/libshared/src
|
||||
${TASK_INCLUDE_DIRS})
|
||||
|
||||
add_library (task STATIC CLI2.cpp
|
||||
Context.cpp
|
||||
DOM.cpp
|
||||
Eval.cpp
|
||||
Filter.cpp
|
||||
Hooks.cpp
|
||||
Lexer.cpp
|
||||
Operation.cpp
|
||||
TF2.cpp
|
||||
TDB2.cpp
|
||||
Task.cpp
|
||||
Variant.cpp
|
||||
Version.cpp
|
||||
ViewTask.cpp
|
||||
add_library (task STATIC CLI2.cpp CLI2.h
|
||||
Context.cpp Context.h
|
||||
DOM.cpp DOM.h
|
||||
Eval.cpp Eval.h
|
||||
Filter.cpp Filter.h
|
||||
Hooks.cpp Hooks.h
|
||||
Lexer.cpp Lexer.h
|
||||
Operation.cpp Operation.h
|
||||
TF2.cpp TF2.h
|
||||
TDB2.cpp TDB2.h
|
||||
Task.cpp Task.h
|
||||
Variant.cpp Variant.h
|
||||
Version.cpp Version.h
|
||||
ViewTask.cpp ViewTask.h
|
||||
dependency.cpp
|
||||
feedback.cpp
|
||||
legacy.cpp
|
||||
|
@ -27,25 +27,26 @@ add_library (task STATIC CLI2.cpp
|
|||
recur.cpp
|
||||
rules.cpp
|
||||
sort.cpp
|
||||
util.cpp)
|
||||
util.cpp util.h)
|
||||
target_link_libraries(task taskchampion-cpp)
|
||||
|
||||
add_library (libshared STATIC libshared/src/Color.cpp
|
||||
libshared/src/Configuration.cpp
|
||||
libshared/src/Datetime.cpp
|
||||
libshared/src/Duration.cpp
|
||||
libshared/src/FS.cpp
|
||||
libshared/src/JSON.cpp
|
||||
libshared/src/Msg.cpp
|
||||
libshared/src/Pig.cpp
|
||||
libshared/src/RX.cpp
|
||||
libshared/src/Table.cpp
|
||||
libshared/src/Timer.cpp
|
||||
libshared/src/format.cpp
|
||||
add_library (libshared STATIC libshared/src/Color.cpp libshared/src/Color.h
|
||||
libshared/src/Configuration.cpp libshared/src/Configuration.h
|
||||
libshared/src/Datetime.cpp libshared/src/Datetime.h
|
||||
libshared/src/Duration.cpp libshared/src/Duration.h
|
||||
libshared/src/FS.cpp libshared/src/FS.h
|
||||
libshared/src/JSON.cpp libshared/src/JSON.h
|
||||
libshared/src/Msg.cpp libshared/src/Msg.h
|
||||
libshared/src/Pig.cpp libshared/src/Pig.h
|
||||
libshared/src/RX.cpp libshared/src/RX.h
|
||||
libshared/src/Table.cpp libshared/src/Table.h
|
||||
libshared/src/Timer.cpp libshared/src/Timer.h
|
||||
libshared/src/format.cpp libshared/src/format.h
|
||||
libshared/src/ip.cpp
|
||||
libshared/src/shared.cpp
|
||||
libshared/src/unicode.cpp
|
||||
libshared/src/utf8.cpp)
|
||||
libshared/src/shared.cpp libshared/src/shared.h
|
||||
libshared/src/unicode.cpp libshared/src/unicode.h
|
||||
libshared/src/utf8.cpp libshared/src/utf8.h
|
||||
libshared/src/wcwidth.h)
|
||||
|
||||
add_executable (task_executable main.cpp)
|
||||
add_executable (calc_executable calc.cpp)
|
||||
|
|
|
@ -36,15 +36,16 @@
|
|||
#include <Version.h>
|
||||
#include <assert.h>
|
||||
#include <format.h>
|
||||
#include <recur.h>
|
||||
#include <rules.h>
|
||||
#include <main.h>
|
||||
#include <rust/cxx.h>
|
||||
#include <shared.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <taskchampion-cpp/lib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
|
@ -54,6 +55,7 @@
|
|||
#include <commit.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef SOLARIS
|
||||
|
@ -596,6 +598,9 @@ int Context::initialize(int argc, const char** argv) {
|
|||
|
||||
createDefaultConfig();
|
||||
|
||||
bool create_if_missing = !config.getBoolean("exit.on.missing.db");
|
||||
tdb2.open_replica(data_dir, create_if_missing);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// [3] Instantiate Command objects and capture command entities.
|
||||
|
@ -669,21 +674,6 @@ int Context::initialize(int argc, const char** argv) {
|
|||
if (foundAssumed) header("No command specified - assuming 'information'.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// [7.5] Open the Replica.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool create_if_missing = !config.getBoolean("exit.on.missing.db");
|
||||
Command* c = commands[cli2.getCommand()];
|
||||
|
||||
// We must allow writes if either 'gc' is enabled and the command performs GC, or the command
|
||||
// itself is read-write.
|
||||
bool read_write =
|
||||
(config.getBoolean("gc") && (c->needs_gc() || c->needs_recur_update())) || !c->read_only();
|
||||
tdb2.open_replica(data_dir, create_if_missing, read_write);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// [8] Initialize hooks.
|
||||
|
@ -862,7 +852,7 @@ int Context::dispatch(std::string& out) {
|
|||
Command* c = commands[command];
|
||||
assert(c);
|
||||
|
||||
// The command know whether they need a GC or recurrence update.
|
||||
// The command know whether they need a GC.
|
||||
if (c->needs_gc()) {
|
||||
tdb2.gc();
|
||||
}
|
||||
|
@ -879,11 +869,6 @@ int Context::dispatch(std::string& out) {
|
|||
if (config.getBoolean("debug") && config.getInteger("debug.parser") == 1)
|
||||
debug(cli2.dump("Parse Tree (before command-specifіc processing)"));
|
||||
|
||||
if (c->needs_recur_update() && Context::getContext().config.getBoolean("gc")) {
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
}
|
||||
|
||||
return c->execute(out);
|
||||
}
|
||||
|
||||
|
@ -1173,13 +1158,6 @@ void Context::staticInitialization() {
|
|||
void Context::createDefaultConfig() {
|
||||
// Do we need to create a default rc?
|
||||
if (rc_file._data != "" && !rc_file.exists()) {
|
||||
// If stdout is not a file, we are probably executing in a completion context and should not
|
||||
// prompt (as the user won't see it) or modify the config (as completion functions are typically
|
||||
// read-only).
|
||||
if (!isatty(STDOUT_FILENO)) {
|
||||
throw std::string("Cannot proceed without rc file.");
|
||||
}
|
||||
|
||||
if (config.getBoolean("confirmation") &&
|
||||
!confirm(format("A configuration file could not be found in {1}\n\nWould you like a sample "
|
||||
"{2} created, so Taskwarrior can proceed?",
|
||||
|
|
|
@ -286,13 +286,6 @@ bool getDOM(const std::string& name, const Task* task, Variant& value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// The "tags" property is deprecated, but it is documented as part of the DOM, so simulate it.
|
||||
if (size == 1 && canonical == "tags") {
|
||||
auto tags = ref->getTags();
|
||||
value = Variant(join(",", tags));
|
||||
return true;
|
||||
}
|
||||
|
||||
Column* column = Context::getContext().columns[canonical];
|
||||
|
||||
if (size == 1 && column) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <Task.h>
|
||||
#include <format.h>
|
||||
#include <shared.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <format.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Take an input set of tasks and filter into a subset.
|
||||
void Filter::subset(const std::vector<Task>& input, std::vector<Task>& output) {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <Task.h>
|
||||
#include <Variant.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Filter {
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <Variant.h>
|
||||
#include <format.h>
|
||||
#include <shared.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
@ -275,7 +276,7 @@ void Hooks::onAdd(Task& task) const {
|
|||
// - all emitted non-JSON lines are considered feedback or error messages
|
||||
// depending on the status code.
|
||||
//
|
||||
void Hooks::onModify(Task& before, Task& after) const {
|
||||
void Hooks::onModify(const Task& before, Task& after) const {
|
||||
if (!_enabled) return;
|
||||
|
||||
Timer timer;
|
||||
|
|
|
@ -40,7 +40,7 @@ class Hooks {
|
|||
void onLaunch() const;
|
||||
void onExit() const;
|
||||
void onAdd(Task&) const;
|
||||
void onModify(Task&, Task&) const;
|
||||
void onModify(const Task&, Task&) const;
|
||||
std::vector<std::string> list() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2006 - 2025, Tomas Babej, Paul Beckingham, Federico Hernandez,
|
||||
// Tobias Predel.
|
||||
// Copyright 2006 - 2024, Tomas Babej, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -25,8 +24,8 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDED_OPERATION
|
||||
#define INCLUDED_OPERATION
|
||||
#ifndef INCLUDED_OPERATIOn
|
||||
#define INCLUDED_OPERATIOn
|
||||
|
||||
#include <taskchampion-cpp/lib.h>
|
||||
|
||||
|
|
31
src/TDB2.cpp
31
src/TDB2.cpp
|
@ -33,11 +33,16 @@
|
|||
#include <TDB2.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
|
@ -45,16 +50,17 @@ bool TDB2::debug_mode = false;
|
|||
static void dependency_scan(std::vector<Task>&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void TDB2::open_replica(const std::string& location, bool create_if_missing, bool read_write) {
|
||||
_replica = tc::new_replica_on_disk(location, create_if_missing, read_write);
|
||||
void TDB2::open_replica(const std::string& location, bool create_if_missing) {
|
||||
_replica = tc::new_replica_on_disk(location, create_if_missing);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void TDB2::open_replica_in_memory() { _replica = tc::new_replica_in_memory(); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Add the new task to the replica.
|
||||
void TDB2::add(Task& task) {
|
||||
// Validate a task for addition. This is stricter than `task.validate`, as any
|
||||
// inconsistency is probably user error.
|
||||
task.validate_add();
|
||||
|
||||
// Ensure the task is consistent, and provide defaults if necessary.
|
||||
// bool argument to validate() is "applyDefault", to apply default values for
|
||||
// properties not otherwise given.
|
||||
|
@ -188,8 +194,11 @@ void TDB2::purge(Task& task) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
rust::Box<tc::Replica>& TDB2::replica() {
|
||||
// One of the open_replica_ methods must be called before this one.
|
||||
assert(_replica);
|
||||
// Create a replica in-memory if `open_replica` has not been called. This
|
||||
// occurs in tests.
|
||||
if (!_replica) {
|
||||
_replica = tc::new_replica_in_memory();
|
||||
}
|
||||
return _replica.value();
|
||||
}
|
||||
|
||||
|
@ -354,7 +363,8 @@ bool TDB2::get(const std::string& uuid, Task& task) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Locate task by UUID, wherever it is.
|
||||
bool TDB2::has(const std::string& uuid) {
|
||||
return replica()->get_task_data(tc::uuid_from_string(uuid)).is_some();
|
||||
Task task;
|
||||
return get(uuid, task);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -440,6 +450,11 @@ int TDB2::num_local_changes() { return (int)replica()->num_local_operations(); }
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int TDB2::num_reverts_possible() { return (int)replica()->num_undo_points(); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void TDB2::dump() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// For any task that has depenencies, follow the chain of dependencies until the
|
||||
// end. Along the way, update the Task::is_blocked and Task::is_blocking data
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
#ifndef INCLUDED_TDB2
|
||||
#define INCLUDED_TDB2
|
||||
|
||||
#include <FS.h>
|
||||
#include <Task.h>
|
||||
#include <stdio.h>
|
||||
#include <taskchampion-cpp/lib.h>
|
||||
|
||||
#include <map>
|
||||
|
@ -44,8 +46,7 @@ class TDB2 {
|
|||
|
||||
TDB2() = default;
|
||||
|
||||
void open_replica(const std::string &, bool create_if_missing, bool read_write);
|
||||
void open_replica_in_memory();
|
||||
void open_replica(const std::string &, bool create_if_missing);
|
||||
void add(Task &);
|
||||
void modify(Task &);
|
||||
void purge(Task &);
|
||||
|
@ -71,6 +72,8 @@ class TDB2 {
|
|||
int num_local_changes();
|
||||
int num_reverts_possible();
|
||||
|
||||
void dump();
|
||||
|
||||
rust::Box<tc::Replica> &replica();
|
||||
|
||||
private:
|
||||
|
|
12
src/TF2.cpp
12
src/TF2.cpp
|
@ -31,12 +31,18 @@
|
|||
#include <Table.h>
|
||||
#include <cmake.h>
|
||||
#include <format.h>
|
||||
#ifdef PRODUCT_TASKWARRIOR
|
||||
#include <legacy.h>
|
||||
#endif
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
#define STRING_TDB2_REVERTED "Modified task reverted."
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -29,9 +29,12 @@
|
|||
|
||||
#include <FS.h>
|
||||
#include <Task.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
// TF2 Class represents a single 2.x-style file in the task database.
|
||||
|
|
38
src/Task.cpp
38
src/Task.cpp
|
@ -58,8 +58,7 @@
|
|||
#include <Eval.h>
|
||||
#include <Filter.h>
|
||||
#include <Variant.h>
|
||||
#include <dependency.h>
|
||||
#include <feedback.h>
|
||||
#include <main.h>
|
||||
|
||||
#define APPROACHING_INFINITY 1000 // Close enough. This isn't rocket surgery.
|
||||
|
||||
|
@ -322,8 +321,8 @@ void Task::setStatus(Task::status status) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Determines status of a date attribute.
|
||||
Task::dateState Task::getDateState(const std::string& name) const {
|
||||
time_t value = get_date(name);
|
||||
if (value > 0) {
|
||||
std::string value = get(name);
|
||||
if (value.length()) {
|
||||
Datetime reference(value);
|
||||
Datetime now;
|
||||
Datetime today("today");
|
||||
|
@ -777,7 +776,7 @@ void Task::parseLegacy(const std::string& line) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Task::composeJSON(bool decorate /*= false*/) {
|
||||
std::string Task::composeJSON(bool decorate /*= false*/) const {
|
||||
std::stringstream out;
|
||||
out << '{';
|
||||
|
||||
|
@ -798,23 +797,20 @@ std::string Task::composeJSON(bool decorate /*= false*/) {
|
|||
// If value is an empty string, do not ever output it
|
||||
if (i.second == "") continue;
|
||||
|
||||
if (attributes_written) out << ',';
|
||||
|
||||
std::string type = Task::attributes[i.first];
|
||||
if (type == "") type = "string";
|
||||
|
||||
// Date fields are written as ISO 8601.
|
||||
if (type == "date") {
|
||||
time_t epoch = get_date(i.first);
|
||||
if (epoch != 0) {
|
||||
Datetime d(i.second);
|
||||
if (attributes_written) out << ',';
|
||||
Datetime d(i.second);
|
||||
out << '"' << (i.first == "modification" ? "modified" : i.first)
|
||||
<< "\":\""
|
||||
// Date was deleted, do not export parsed empty string
|
||||
<< (i.second == "" ? "" : d.toISO()) << '"';
|
||||
|
||||
out << '"' << (i.first == "modification" ? "modified" : i.first)
|
||||
<< "\":\""
|
||||
// Date was deleted, do not export parsed empty string
|
||||
<< (i.second == "" ? "" : d.toISO()) << '"';
|
||||
|
||||
++attributes_written;
|
||||
}
|
||||
++attributes_written;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -824,8 +820,6 @@ std::string Task::composeJSON(bool decorate /*= false*/) {
|
|||
}
|
||||
*/
|
||||
else if (type == "numeric") {
|
||||
if (attributes_written) out << ',';
|
||||
|
||||
out << '"' << i.first << "\":" << i.second;
|
||||
|
||||
++attributes_written;
|
||||
|
@ -833,8 +827,6 @@ std::string Task::composeJSON(bool decorate /*= false*/) {
|
|||
|
||||
// Everything else is a quoted value.
|
||||
else {
|
||||
if (attributes_written) out << ',';
|
||||
|
||||
out << '"' << i.first << "\":\"" << (type == "string" ? json::encode(i.second) : i.second)
|
||||
<< '"';
|
||||
|
||||
|
@ -894,7 +886,7 @@ std::string Task::composeJSON(bool decorate /*= false*/) {
|
|||
|
||||
#ifdef PRODUCT_TASKWARRIOR
|
||||
// Include urgency.
|
||||
if (decorate) out << ',' << "\"urgency\":" << urgency();
|
||||
if (decorate) out << ',' << "\"urgency\":" << urgency_c();
|
||||
#endif
|
||||
|
||||
out << '}';
|
||||
|
@ -928,7 +920,7 @@ void Task::addAnnotation(const std::string& description) {
|
|||
++now;
|
||||
} while (has(key));
|
||||
|
||||
data[key] = description;
|
||||
data[key] = json::decode(description);
|
||||
++annotation_count;
|
||||
recalc_urgency = true;
|
||||
}
|
||||
|
@ -1999,7 +1991,7 @@ void Task::modify(modType type, bool text_required /* = false */) {
|
|||
// Delegate modification to the column object or their base classes.
|
||||
if (name == "depends" || name == "tags" || name == "recur" || column->type() == "date" ||
|
||||
column->type() == "duration" || column->type() == "numeric" ||
|
||||
column->type() == "string" || column->type() == "uuid") {
|
||||
column->type() == "string") {
|
||||
column->modify(*this, value);
|
||||
mods = true;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <Datetime.h>
|
||||
#include <JSON.h>
|
||||
#include <Table.h>
|
||||
#include <stdio.h>
|
||||
#include <taskchampion-cpp/lib.h>
|
||||
#include <time.h>
|
||||
|
||||
|
@ -68,7 +69,7 @@ class Task {
|
|||
Task(rust::Box<tc::TaskData>);
|
||||
|
||||
void parse(const std::string&);
|
||||
std::string composeJSON(bool decorate = false);
|
||||
std::string composeJSON(bool decorate = false) const;
|
||||
|
||||
// Status values.
|
||||
enum status { pending, completed, deleted, recurring, waiting };
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#define STRING_VARIANT_DIV_DUR_BOOL "Cannot divide duration by Boolean"
|
||||
#define STRING_VARIANT_DIV_DUR_STR "Cannot divide durations by strings"
|
||||
#define STRING_VARIANT_DIV_DUR_DATE "Cannot divide durations by dates"
|
||||
#define STRING_VARIANT_DIV_DUR_DUR "Cannot divide durations by durations"
|
||||
#define STRING_VARIANT_MOD_BOOL "Cannot modulo Booleans"
|
||||
#define STRING_VARIANT_MOD_DATE "Cannot modulo date values"
|
||||
#define STRING_VARIANT_MOD_DUR "Cannot modulo duration values"
|
||||
|
@ -1759,9 +1760,7 @@ Variant& Variant::operator/=(const Variant& other) {
|
|||
throw std::string(STRING_VARIANT_DIV_DUR_DATE);
|
||||
|
||||
case type_duration:
|
||||
_type = type_real;
|
||||
_real = static_cast<double>(_duration) / static_cast<double>(right._duration);
|
||||
break;
|
||||
throw std::string(STRING_VARIANT_DIV_DUR_DUR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#define INCLUDED_VARIANT
|
||||
|
||||
#include <Task.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class Variant {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <Context.h>
|
||||
#include <ViewTask.h>
|
||||
#include <format.h>
|
||||
#include <rules.h>
|
||||
#include <main.h>
|
||||
#include <utf8.h>
|
||||
#include <util.h>
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@
|
|||
#include <ColDepends.h>
|
||||
#include <Context.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <stdlib.h>
|
||||
#include <utf8.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
|
||||
#define STRING_COLUMN_LABEL_DEP "Depends"
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include <Eval.h>
|
||||
#include <Filter.h>
|
||||
#include <Variant.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <utf8.h>
|
||||
|
||||
|
|
|
@ -56,9 +56,11 @@ void ColumnTypeDuration::modify(Task& task, const std::string& value) {
|
|||
evaluatedValue = Variant(value);
|
||||
}
|
||||
|
||||
// The duration is first parsed, then stored inside the variant as a `time_t`
|
||||
// The duration is stored in raw form, but it must still be valid,
|
||||
// and therefore is parsed first.
|
||||
std::string label = " [1;37;43mMODIFICATION[0m ";
|
||||
if (evaluatedValue.type() == Variant::type_duration) {
|
||||
// Store the raw value, for 'recur'.
|
||||
Context::getContext().debug(label + _name + " <-- " + (std::string)evaluatedValue + " <-- '" +
|
||||
value + '\'');
|
||||
task.set(_name, evaluatedValue);
|
||||
|
|
|
@ -297,23 +297,3 @@ void ColumnUDADuration::render(std::vector<std::string>& lines, Task& task, int
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
ColumnUDAUUID::ColumnUDAUUID() {
|
||||
_name = "<uda>";
|
||||
_type = "uuid";
|
||||
_style = "long";
|
||||
_label = "";
|
||||
_modifiable = true;
|
||||
_uda = true;
|
||||
_styles = {"long", "short"};
|
||||
_examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool ColumnUDAUUID::validate(const std::string& input) const {
|
||||
Lexer lex(input);
|
||||
std::string token;
|
||||
Lexer::Type type;
|
||||
return lex.isUUID(token, type, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <ColTypeDuration.h>
|
||||
#include <ColTypeNumeric.h>
|
||||
#include <ColTypeString.h>
|
||||
#include <ColUUID.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class ColumnUDAString : public ColumnTypeString {
|
||||
|
@ -84,12 +83,5 @@ class ColumnUDADuration : public ColumnTypeDuration {
|
|||
std::vector<std::string> _values;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class ColumnUDAUUID : public ColumnUUID {
|
||||
public:
|
||||
ColumnUDAUUID();
|
||||
bool validate(const std::string&) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -246,15 +246,9 @@ Column* Column::uda(const std::string& name) {
|
|||
c->_label = label;
|
||||
if (values != "") c->_values = split(values, ',');
|
||||
return c;
|
||||
} else if (type == "uuid") {
|
||||
auto c = new ColumnUDAUUID();
|
||||
c->_name = name;
|
||||
c->_label = label;
|
||||
return c;
|
||||
} else if (type != "")
|
||||
throw std::string(
|
||||
"User defined attributes may only be of type 'string', 'uuid', date', 'duration' or "
|
||||
"'numeric'.");
|
||||
"User defined attributes may only be of type 'string', 'date', 'duration' or 'numeric'.");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
#include <CmdAdd.h>
|
||||
#include <Context.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdAdd::CmdAdd() {
|
||||
|
@ -40,7 +40,6 @@ CmdAdd::CmdAdd() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = true;
|
||||
|
@ -56,11 +55,6 @@ int CmdAdd::execute(std::string& output) {
|
|||
// the task is empty, but DOM references can refer to earlier parts of the
|
||||
// command line, e.g., `task add due:20110101 wait:due`.
|
||||
task.modify(Task::modReplace, true);
|
||||
|
||||
// Validate a task for addition. This is stricter than `task.validate`, as any
|
||||
// inconsistency is probably user error.
|
||||
task.validate_add();
|
||||
|
||||
Context::getContext().tdb2.add(task);
|
||||
|
||||
// Do not display ID 0, users cannot query by that
|
||||
|
|
|
@ -39,7 +39,6 @@ CmdCompletionAliases::CmdCompletionAliases() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <CmdAnnotate.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -44,7 +44,6 @@ CmdAnnotate::CmdAnnotate() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <CmdAppend.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -44,7 +44,6 @@ CmdAppend::CmdAppend() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -42,7 +42,6 @@ CmdZshAttributes::CmdZshAttributes() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <Duration.h>
|
||||
#include <Filter.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <math.h>
|
||||
#include <shared.h>
|
||||
#include <string.h>
|
||||
|
@ -766,7 +767,6 @@ CmdBurndownMonthly::CmdBurndownMonthly() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -779,6 +779,8 @@ int CmdBurndownMonthly::execute(std::string& output) {
|
|||
int rc = 0;
|
||||
|
||||
// Scan the pending tasks, applying any filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -799,7 +801,6 @@ CmdBurndownWeekly::CmdBurndownWeekly() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -812,6 +813,8 @@ int CmdBurndownWeekly::execute(std::string& output) {
|
|||
int rc = 0;
|
||||
|
||||
// Scan the pending tasks, applying any filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -832,7 +835,6 @@ CmdBurndownDaily::CmdBurndownDaily() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -845,6 +847,8 @@ int CmdBurndownDaily::execute(std::string& output) {
|
|||
int rc = 0;
|
||||
|
||||
// Scan the pending tasks, applying any filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
|
|
@ -37,7 +37,6 @@ CmdCalc::CmdCalc() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <Lexer.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <stdlib.h>
|
||||
#include <utf8.h>
|
||||
|
@ -48,7 +49,6 @@ CmdCalendar::CmdCalendar() {
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -80,6 +80,8 @@ int CmdCalendar::execute(std::string& output) {
|
|||
monthsPerLine = preferredMonthsPerLine;
|
||||
|
||||
// Load the pending tasks.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
auto tasks = Context::getContext().tdb2.pending_tasks();
|
||||
|
||||
Datetime today;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <Context.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <sstream>
|
||||
|
@ -44,7 +45,6 @@ CmdColor::CmdColor() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <Color.h>
|
||||
#include <Context.h>
|
||||
#include <Table.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <util.h>
|
||||
|
||||
|
@ -44,7 +45,6 @@ CmdColumns::CmdColumns() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -119,7 +119,6 @@ CmdCompletionColumns::CmdCompletionColumns() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -45,7 +45,6 @@ CmdCommands::CmdCommands() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -62,7 +61,6 @@ int CmdCommands::execute(std::string& output) {
|
|||
view.add("R/W", false);
|
||||
view.add("ID", false);
|
||||
view.add("GC", false);
|
||||
view.add("Recur", false);
|
||||
view.add("Context", false);
|
||||
view.add("Filter", false);
|
||||
view.add("Mods", false);
|
||||
|
@ -87,17 +85,15 @@ int CmdCommands::execute(std::string& output) {
|
|||
|
||||
if (command.second->needs_gc()) view.set(row, 4, "GC");
|
||||
|
||||
if (command.second->needs_recur_update()) view.set(row, 5, "Recur");
|
||||
if (command.second->uses_context()) view.set(row, 5, "Ctxt");
|
||||
|
||||
if (command.second->uses_context()) view.set(row, 6, "Ctxt");
|
||||
if (command.second->accepts_filter()) view.set(row, 6, "Filt");
|
||||
|
||||
if (command.second->accepts_filter()) view.set(row, 7, "Filt");
|
||||
if (command.second->accepts_modifications()) view.set(row, 7, "Mods");
|
||||
|
||||
if (command.second->accepts_modifications()) view.set(row, 8, "Mods");
|
||||
if (command.second->accepts_miscellaneous()) view.set(row, 8, "Misc");
|
||||
|
||||
if (command.second->accepts_miscellaneous()) view.set(row, 9, "Misc");
|
||||
|
||||
view.set(row, 10, command.second->description());
|
||||
view.set(row, 9, command.second->description());
|
||||
}
|
||||
|
||||
output = optionalBlankLine() + view.render() + optionalBlankLine() + '\n';
|
||||
|
|
|
@ -44,7 +44,6 @@ CmdConfig::CmdConfig() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -218,7 +217,6 @@ CmdCompletionConfig::CmdCompletionConfig() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <rules.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <util.h>
|
||||
|
||||
|
@ -49,7 +49,6 @@ CmdContext::CmdContext() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -218,8 +217,8 @@ void CmdContext::defineContext(const std::vector<std::string>& words, std::strin
|
|||
if (!valid_write_context) {
|
||||
std::stringstream warning;
|
||||
warning
|
||||
<< format("The filter '{1}' is not a valid modification string, because it {2}.", value,
|
||||
reason)
|
||||
<< format("The filter '{1}' is not a valid modification string, because it contains {2}.",
|
||||
value, reason)
|
||||
<< "\nAs such, value for the write context cannot be set (context will not apply on task "
|
||||
"add / task log).\n\n"
|
||||
<< format(
|
||||
|
@ -415,7 +414,6 @@ CmdCompletionContext::CmdCompletionContext() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <CmdCount.h>
|
||||
#include <Filter.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdCount::CmdCount() {
|
||||
|
@ -39,7 +40,6 @@ CmdCount::CmdCount() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -50,6 +50,8 @@ CmdCount::CmdCount() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdCount::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
|
|
@ -34,15 +34,15 @@
|
|||
#include <Lexer.h>
|
||||
#include <Version.h>
|
||||
#include <ViewTask.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <legacy.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <sort.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
|
@ -55,7 +55,6 @@ CmdCustom::CmdCustom(const std::string& keyword, const std::string& usage,
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -101,6 +100,10 @@ int CmdCustom::execute(std::string& output) {
|
|||
// Add the report filter to any existing filter.
|
||||
if (reportFilter != "") Context::getContext().cli2.addFilter(reportFilter);
|
||||
|
||||
// Make sure reccurent tasks are generated.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
|
||||
// Apply filter.
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
|
|
|
@ -30,10 +30,8 @@
|
|||
#include <CmdDelete.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <dependency.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <recur.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -51,7 +49,6 @@ CmdDelete::CmdDelete() {
|
|||
_displays_id = false;
|
||||
_needs_confirm = true;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <CmdDenotate.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <util.h>
|
||||
|
||||
|
@ -49,7 +49,6 @@ CmdDenotate::CmdDenotate() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -50,7 +50,6 @@ CmdDiagnostics::CmdDiagnostics() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -30,11 +30,8 @@
|
|||
#include <CmdDone.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <dependency.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <nag.h>
|
||||
#include <recur.h>
|
||||
#include <main.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -47,7 +44,6 @@ CmdDone::CmdDone() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <CmdDuplicate.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -44,7 +44,6 @@ CmdDuplicate::CmdDuplicate() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <Lexer.h>
|
||||
#include <Pig.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
@ -63,7 +64,6 @@ CmdEdit::CmdEdit() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -77,6 +77,8 @@ CmdEdit::CmdEdit() {
|
|||
// wrench. To be used sparingly.
|
||||
int CmdEdit::execute(std::string&) {
|
||||
// Filter the tasks.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -317,6 +319,7 @@ void CmdEdit::parseTask(Task& task, const std::string& after, const std::string&
|
|||
|
||||
// tags
|
||||
value = findValue(after, "\n Tags:");
|
||||
task.remove("tags");
|
||||
task.setTags(split(value, ' '));
|
||||
|
||||
// description.
|
||||
|
@ -618,9 +621,10 @@ CmdEdit::editResult CmdEdit::editFile(Task& task) {
|
|||
auto dateformat = Context::getContext().config.get("dateformat.edit");
|
||||
if (dateformat == "") dateformat = Context::getContext().config.get("dateformat");
|
||||
|
||||
// Change directory for the editor, doing nothing on error.
|
||||
// Change directory for the editor
|
||||
auto current_dir = Directory::cwd();
|
||||
chdir(location._data.c_str());
|
||||
int ignored = chdir(location._data.c_str());
|
||||
++ignored; // Keep compiler quiet.
|
||||
|
||||
// Check if the file already exists, if so, bail out
|
||||
Path filepath = Path(file.str());
|
||||
|
@ -700,7 +704,7 @@ ARE_THESE_REALLY_HARMFUL:
|
|||
|
||||
// Cleanup.
|
||||
File::remove(file.str());
|
||||
chdir(current_dir.c_str());
|
||||
ignored = chdir(current_dir.c_str());
|
||||
return changes ? CmdEdit::editResult::changes : CmdEdit::editResult::nochanges;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ CmdExec::CmdExec() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -31,9 +31,8 @@
|
|||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <format.h>
|
||||
#include <legacy.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <sort.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdExport::CmdExport() {
|
||||
|
@ -43,7 +42,6 @@ CmdExport::CmdExport() {
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -84,6 +82,10 @@ int CmdExport::execute(std::string& output) {
|
|||
// Add the report filter to any existing filter.
|
||||
if (reportFilter != "") Context::getContext().cli2.addFilter(reportFilter);
|
||||
|
||||
// Make sure reccurent tasks are generated.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
|
||||
// Apply filter.
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <DOM.h>
|
||||
#include <Variant.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -42,7 +43,6 @@ CmdGet::CmdGet() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -44,7 +44,6 @@ CmdHelp::CmdHelp() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <sstream>
|
||||
|
@ -54,7 +55,6 @@ CmdHistoryBase<HistoryStrategy>::CmdHistoryBase() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -293,6 +293,8 @@ int CmdHistoryBase<HistoryStrategy>::execute(std::string& output) {
|
|||
completedGroup.clear();
|
||||
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <CmdIDs.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -45,7 +46,6 @@ CmdIDs::CmdIDs() {
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -56,6 +56,8 @@ CmdIDs::CmdIDs() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdIDs::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -125,7 +127,6 @@ CmdCompletionIds::CmdCompletionIds() {
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -136,6 +137,8 @@ CmdCompletionIds::CmdCompletionIds() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdCompletionIds::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -160,7 +163,6 @@ CmdZshCompletionIds::CmdZshCompletionIds() {
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -171,6 +173,8 @@ CmdZshCompletionIds::CmdZshCompletionIds() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdZshCompletionIds::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -195,7 +199,6 @@ CmdUUIDs::CmdUUIDs() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -206,6 +209,8 @@ CmdUUIDs::CmdUUIDs() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdUUIDs::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -229,7 +234,6 @@ CmdCompletionUuids::CmdCompletionUuids() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -240,6 +244,8 @@ CmdCompletionUuids::CmdCompletionUuids() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdCompletionUuids::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
@ -263,7 +269,6 @@ CmdZshCompletionUuids::CmdZshCompletionUuids() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -274,6 +279,8 @@ CmdZshCompletionUuids::CmdZshCompletionUuids() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdZshCompletionUuids::execute(std::string& output) {
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
|
|
@ -45,7 +45,6 @@ CmdImport::CmdImport() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -46,7 +46,6 @@ CmdImportV2::CmdImportV2() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <JSON.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class CmdImportV2 : public Command {
|
||||
public:
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
#include <Filter.h>
|
||||
#include <Lexer.h>
|
||||
#include <Operation.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <rules.h>
|
||||
#include <main.h>
|
||||
#include <math.h>
|
||||
#include <shared.h>
|
||||
#include <stdlib.h>
|
||||
#include <taskchampion-cpp/lib.h>
|
||||
|
@ -59,7 +59,6 @@ CmdInfo::CmdInfo() {
|
|||
// Once the test suite is completely modified, this can be corrected.
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -120,11 +119,9 @@ int CmdInfo::execute(std::string& output) {
|
|||
description += '\n' + std::string(indent, ' ') +
|
||||
Datetime(anno.first.substr(11)).toString(dateformatanno) + ' ' + anno.second;
|
||||
|
||||
if (task.has("description")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Description");
|
||||
view.set(row, 1, description, c);
|
||||
}
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Description");
|
||||
view.set(row, 1, description, c);
|
||||
|
||||
// status
|
||||
row = view.addRow();
|
||||
|
@ -217,76 +214,64 @@ int CmdInfo::execute(std::string& output) {
|
|||
}
|
||||
|
||||
// entry
|
||||
if (task.has("entry") && task.get_date("entry")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Entered");
|
||||
Datetime dt(task.get_date("entry"));
|
||||
std::string entry = dt.toString(dateformat);
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Entered");
|
||||
Datetime dt(task.get_date("entry"));
|
||||
std::string entry = dt.toString(dateformat);
|
||||
|
||||
std::string age;
|
||||
auto created = task.get("entry");
|
||||
if (created.length()) {
|
||||
Datetime dt(strtoll(created.c_str(), nullptr, 10));
|
||||
age = Duration(now - dt).formatVague();
|
||||
}
|
||||
|
||||
view.set(row, 1, entry + " (" + age + ')');
|
||||
std::string age;
|
||||
auto created = task.get("entry");
|
||||
if (created.length()) {
|
||||
Datetime dt(strtoll(created.c_str(), nullptr, 10));
|
||||
age = Duration(now - dt).formatVague();
|
||||
}
|
||||
|
||||
auto validDate = [&](const char* prop) {
|
||||
if (!task.has(prop)) {
|
||||
return false;
|
||||
}
|
||||
if (task.get_date(prop) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
view.set(row, 1, entry + " (" + age + ')');
|
||||
|
||||
// wait
|
||||
if (validDate("wait")) {
|
||||
if (task.has("wait")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Waiting until");
|
||||
view.set(row, 1, Datetime(task.get_date("wait")).toString(dateformat));
|
||||
}
|
||||
|
||||
// scheduled
|
||||
if (validDate("scheduled")) {
|
||||
if (task.has("scheduled")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Scheduled");
|
||||
view.set(row, 1, Datetime(task.get_date("scheduled")).toString(dateformat));
|
||||
}
|
||||
|
||||
// start
|
||||
if (validDate("start")) {
|
||||
if (task.has("start")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Start");
|
||||
view.set(row, 1, Datetime(task.get_date("start")).toString(dateformat));
|
||||
}
|
||||
|
||||
// due (colored)
|
||||
if (validDate("due")) {
|
||||
if (task.has("due")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Due");
|
||||
view.set(row, 1, Datetime(task.get_date("due")).toString(dateformat));
|
||||
}
|
||||
|
||||
// end
|
||||
if (validDate("end")) {
|
||||
if (task.has("end")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "End");
|
||||
view.set(row, 1, Datetime(task.get_date("end")).toString(dateformat));
|
||||
}
|
||||
|
||||
// until
|
||||
if (validDate("until")) {
|
||||
if (task.has("until")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Until");
|
||||
view.set(row, 1, Datetime(task.get_date("until")).toString(dateformat));
|
||||
}
|
||||
|
||||
// modified
|
||||
if (validDate("modified")) {
|
||||
if (task.has("modified")) {
|
||||
row = view.addRow();
|
||||
view.set(row, 0, "Last modified");
|
||||
|
||||
|
@ -646,11 +631,7 @@ std::optional<std::string> CmdInfo::formatForInfo(const std::vector<Operation>&
|
|||
} else {
|
||||
// Record the last start time for later duration calculation.
|
||||
if (prop == "start") {
|
||||
try {
|
||||
last_start = Datetime(value.value()).toEpoch();
|
||||
} catch (std::string) {
|
||||
// ignore invalid dates
|
||||
}
|
||||
last_start = Datetime(value.value()).toEpoch();
|
||||
}
|
||||
|
||||
out << format("{1} set to '{2}'.", Lexer::ucFirst(prop),
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
#include <CmdLog.h>
|
||||
#include <Context.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdLog::CmdLog() {
|
||||
|
@ -40,7 +40,6 @@ CmdLog::CmdLog() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -39,7 +39,6 @@ CmdLogo::CmdLogo() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -30,9 +30,8 @@
|
|||
#include <CmdModify.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <recur.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -49,7 +48,6 @@ CmdModify::CmdModify() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
@ -120,7 +118,7 @@ void CmdModify::checkConsistency(Task &before, Task &after) {
|
|||
throw std::string("You cannot remove the recurrence from a recurring task.");
|
||||
|
||||
if ((before.getStatus() == Task::pending) && (after.getStatus() == Task::pending) &&
|
||||
(before.get("end") == "") && (after.get("end") != ""))
|
||||
(after.get("end") != ""))
|
||||
throw format("Could not modify task {1}. You cannot set an end date on a pending task.",
|
||||
before.identifier(true));
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <Duration.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <util.h>
|
||||
|
||||
|
@ -56,7 +57,6 @@ CmdNews::CmdNews() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -160,7 +160,6 @@ std::vector<NewsItem> NewsItem::all() {
|
|||
version3_1_0(items);
|
||||
version3_2_0(items);
|
||||
version3_3_0(items);
|
||||
version3_4_0(items);
|
||||
return items;
|
||||
}
|
||||
|
||||
|
@ -531,21 +530,6 @@ void NewsItem::version3_3_0(std::vector<NewsItem>& items) {
|
|||
items.push_back(info);
|
||||
}
|
||||
|
||||
void NewsItem::version3_4_0(std::vector<NewsItem>& items) {
|
||||
Version version("3.4.0");
|
||||
NewsItem info{version,
|
||||
/*title=*/"Read-Only Access",
|
||||
/*bg_title=*/"",
|
||||
/*background=*/"",
|
||||
/*punchline=*/"Some Taskwarrior commands operate faster in read-only mode",
|
||||
/*update=*/
|
||||
"Some commands do not need to write to the DB, so can open it in read-only\n"
|
||||
"mode and thus more quickly. This does not include reports (task lists),\n"
|
||||
"unless the `gc` config is false. Use `rc.gc=0` in command-lines to allow\n"
|
||||
"read-only access.\n\n"};
|
||||
items.push_back(info);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdNews::execute(std::string& output) {
|
||||
auto words = Context::getContext().cli2.getWords();
|
||||
|
@ -588,10 +572,61 @@ int CmdNews::execute(std::string& output) {
|
|||
}
|
||||
wait_for_enter();
|
||||
|
||||
// Display outro
|
||||
Datetime now;
|
||||
Datetime beginning(2006, 11, 29);
|
||||
Duration development_time = Duration(now - beginning);
|
||||
|
||||
Color underline = Color("underline");
|
||||
|
||||
std::stringstream outro;
|
||||
outro << underline.colorize(bold.colorize("Taskwarrior crowdfunding\n"));
|
||||
outro << format(
|
||||
"Taskwarrior has been in development for {1} years but its survival\n"
|
||||
"depends on your support!\n\n"
|
||||
"Please consider joining our {2} fundraiser to help us fund maintenance\n"
|
||||
"and development of new features:\n\n",
|
||||
std::lround(static_cast<float>(development_time.days()) / 365.25), now.year());
|
||||
outro << bold.colorize(" https://github.com/sponsors/GothenburgBitFactory/\n\n");
|
||||
outro << "Perks are available for our sponsors.\n";
|
||||
|
||||
std::cout << outro.str();
|
||||
|
||||
// Set a mark in the config to remember which version's release notes were displayed
|
||||
if (news_version < current_version) {
|
||||
if (news_version != current_version) {
|
||||
CmdConfig::setConfigVariable("news.version", std::string(current_version), false);
|
||||
}
|
||||
|
||||
// Revert back to default signal handling after displaying the outro
|
||||
signal(SIGINT, SIG_DFL);
|
||||
|
||||
std::string question = format(
|
||||
"\nWould you like to open Taskwarrior {1} fundraising campaign to read more?", now.year());
|
||||
|
||||
std::vector<std::string> options{"yes", "no"};
|
||||
std::vector<std::string> matches;
|
||||
|
||||
std::cout << question << " (YES/no) ";
|
||||
|
||||
std::string answer;
|
||||
std::getline(std::cin, answer);
|
||||
|
||||
if (std::cin.eof() || trim(answer).empty())
|
||||
answer = "yes";
|
||||
else
|
||||
lowerCase(trim(answer));
|
||||
|
||||
autoComplete(answer, options, matches, 1); // Hard-coded 1.
|
||||
|
||||
if (matches.size() == 1 && matches[0] == "yes")
|
||||
#if defined(DARWIN)
|
||||
system("open 'https://github.com/sponsors/GothenburgBitFactory/'");
|
||||
#else
|
||||
system("xdg-open 'https://github.com/sponsors/GothenburgBitFactory/'");
|
||||
#endif
|
||||
|
||||
std::cout << std::endl;
|
||||
} else
|
||||
wait_for_enter(); // Do not display the outro and footnote at once
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -606,8 +641,8 @@ bool CmdNews::should_nag() {
|
|||
|
||||
Version current_version = Version::Current();
|
||||
|
||||
if (news_version >= current_version) {
|
||||
return false;
|
||||
if (news_version == current_version) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if there are actually any interesting news items to show.
|
||||
|
|
|
@ -53,7 +53,6 @@ class NewsItem {
|
|||
static void version3_1_0(std::vector<NewsItem>&);
|
||||
static void version3_2_0(std::vector<NewsItem>&);
|
||||
static void version3_3_0(std::vector<NewsItem>&);
|
||||
static void version3_4_0(std::vector<NewsItem>&);
|
||||
|
||||
private:
|
||||
NewsItem(Version, const std::string&, const std::string& = "", const std::string& = "",
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <CmdPrepend.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -44,7 +44,6 @@ CmdPrepend::CmdPrepend() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -32,9 +32,10 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <sort.h>
|
||||
#include <main.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -46,7 +47,6 @@ CmdProjects::CmdProjects() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -59,6 +59,8 @@ int CmdProjects::execute(std::string& output) {
|
|||
int rc = 0;
|
||||
|
||||
// Get all the tasks.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
auto tasks = Context::getContext().tdb2.pending_tasks();
|
||||
|
||||
if (Context::getContext().config.getBoolean("list.all.projects"))
|
||||
|
@ -139,7 +141,6 @@ CmdCompletionProjects::CmdCompletionProjects() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -150,6 +151,8 @@ CmdCompletionProjects::CmdCompletionProjects() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdCompletionProjects::execute(std::string& output) {
|
||||
// Get all the tasks.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
auto tasks = Context::getContext().tdb2.pending_tasks();
|
||||
|
||||
if (Context::getContext().config.getBoolean("list.all.projects"))
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <CmdPurge.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,7 +43,6 @@ CmdPurge::CmdPurge() {
|
|||
_displays_id = false;
|
||||
_needs_confirm = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -43,7 +43,6 @@ CmdReports::CmdReports() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <FS.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <legacy.h>
|
||||
#include <main.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -53,7 +53,6 @@ CmdShow::CmdShow() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -30,11 +30,8 @@
|
|||
#include <CmdStart.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <dependency.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <nag.h>
|
||||
#include <recur.h>
|
||||
#include <main.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -47,7 +44,6 @@ CmdStart::CmdStart() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
|
@ -48,7 +49,6 @@ CmdStats::CmdStats() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -30,10 +30,8 @@
|
|||
#include <CmdStop.h>
|
||||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <dependency.h>
|
||||
#include <feedback.h>
|
||||
#include <format.h>
|
||||
#include <recur.h>
|
||||
#include <main.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -45,7 +43,6 @@ CmdStop::CmdStop() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = true;
|
||||
|
|
|
@ -33,10 +33,11 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <sort.h>
|
||||
#include <main.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -48,7 +49,6 @@ CmdSummary::CmdSummary() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -65,6 +65,8 @@ int CmdSummary::execute(std::string& output) {
|
|||
bool showAllProjects = Context::getContext().config.getBoolean("summary.all.projects");
|
||||
|
||||
// Apply filter.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
|
|
@ -32,11 +32,13 @@
|
|||
#include <Context.h>
|
||||
#include <Filter.h>
|
||||
#include <format.h>
|
||||
#include <inttypes.h>
|
||||
#include <shared.h>
|
||||
#include <signal.h>
|
||||
#include <taskchampion-cpp/lib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <regex>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -47,7 +49,6 @@ CmdSync::CmdSync() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -79,12 +80,6 @@ int CmdSync::execute(std::string& output) {
|
|||
out << "sync.server.origin is deprecated. Use sync.server.url instead.\n";
|
||||
}
|
||||
|
||||
// redact credentials from `server_url`, if present
|
||||
std::regex remove_creds_regex("^(https?://.+):(.+)@(.+)");
|
||||
std::string safe_server_url = std::regex_replace(server_url, remove_creds_regex, "$1:****@$3");
|
||||
|
||||
auto num_local_operations = replica->num_local_operations();
|
||||
|
||||
if (server_dir != "") {
|
||||
if (verbose) {
|
||||
out << format("Syncing with {1}", server_dir) << '\n';
|
||||
|
@ -137,7 +132,6 @@ int CmdSync::execute(std::string& output) {
|
|||
replica->sync_to_aws_with_default_creds(aws_region, aws_bucket, encryption_secret,
|
||||
avoid_snapshots);
|
||||
}
|
||||
|
||||
} else if (gcp_bucket != "") {
|
||||
std::string gcp_credential_path = Context::getContext().config.get("sync.gcp.credential_path");
|
||||
if (encryption_secret == "") {
|
||||
|
@ -147,17 +141,15 @@ int CmdSync::execute(std::string& output) {
|
|||
out << format("Syncing with GCP bucket {1}", gcp_bucket) << '\n';
|
||||
}
|
||||
replica->sync_to_gcp(gcp_bucket, gcp_credential_path, encryption_secret, avoid_snapshots);
|
||||
|
||||
} else if (server_url != "") {
|
||||
if (client_id == "" || encryption_secret == "") {
|
||||
throw std::string("sync.server.client_id and sync.encryption_secret are required");
|
||||
}
|
||||
if (verbose) {
|
||||
out << format("Syncing with sync server at {1}", safe_server_url) << '\n';
|
||||
out << format("Syncing with sync server at {1}", server_url) << '\n';
|
||||
}
|
||||
replica->sync_to_remote(server_url, tc::uuid_from_string(client_id), encryption_secret,
|
||||
avoid_snapshots);
|
||||
|
||||
} else {
|
||||
throw std::string("No sync.* settings are configured. See task-sync(5).");
|
||||
}
|
||||
|
@ -166,15 +158,6 @@ int CmdSync::execute(std::string& output) {
|
|||
context.tdb2.expire_tasks();
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
out << "Success!\n";
|
||||
// Taskchampion does not provide a measure of the number of operations received from
|
||||
// the server, but we can give some indication of the number sent.
|
||||
if (num_local_operations) {
|
||||
out << format("Sent {1} local operations to the server", num_local_operations) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
output = out.str();
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <sstream>
|
||||
|
@ -45,7 +46,6 @@ CmdTags::CmdTags() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = true;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -136,7 +136,6 @@ CmdCompletionTags::CmdCompletionTags() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
#include <Filter.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <rules.h>
|
||||
#include <main.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -47,7 +48,6 @@ CmdTimesheet::CmdTimesheet() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = true;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
@ -90,6 +90,8 @@ int CmdTimesheet::execute(std::string& output) {
|
|||
}
|
||||
|
||||
// Apply filter to get a set of tasks.
|
||||
handleUntil();
|
||||
handleRecurrence();
|
||||
Filter filter;
|
||||
std::vector<Task> filtered;
|
||||
filter.subset(filtered);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <Table.h>
|
||||
#include <Task.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <util.h>
|
||||
|
||||
|
@ -47,7 +48,6 @@ CmdUDAs::CmdUDAs() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -156,7 +156,6 @@ CmdCompletionUDAs::CmdCompletionUDAs() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -31,11 +31,12 @@
|
|||
#include <Context.h>
|
||||
#include <Operation.h>
|
||||
#include <Task.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdUndo::CmdUndo() {
|
||||
_keyword = "undo";
|
||||
|
@ -44,7 +45,6 @@ CmdUndo::CmdUndo() {
|
|||
_read_only = false;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -102,7 +102,7 @@ bool CmdUndo::confirm_revert(const std::vector<Operation>& undo_ops) {
|
|||
view.set(row, 1, mods.str());
|
||||
}
|
||||
last_uuid = op.get_uuid();
|
||||
mods = std::stringstream();
|
||||
mods.clear();
|
||||
}
|
||||
|
||||
if (op.is_create()) {
|
||||
|
|
|
@ -43,7 +43,6 @@ CmdUnique::CmdUnique() {
|
|||
_read_only = true;
|
||||
_displays_id = true;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <Filter.h>
|
||||
#include <Lexer.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
@ -43,7 +45,6 @@ CmdUrgency::CmdUrgency() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = true;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = true;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <Context.h>
|
||||
#include <Datetime.h>
|
||||
#include <Table.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sstream>
|
||||
#ifdef HAVE_COMMIT
|
||||
|
@ -47,7 +48,6 @@ CmdVersion::CmdVersion() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
@ -101,7 +101,6 @@ CmdCompletionVersion::CmdCompletionVersion() {
|
|||
_read_only = true;
|
||||
_displays_id = false;
|
||||
_needs_gc = false;
|
||||
_needs_recur_update = false;
|
||||
_uses_context = false;
|
||||
_accepts_filter = false;
|
||||
_accepts_modifications = false;
|
||||
|
|
|
@ -50,7 +50,9 @@
|
|||
#include <CmdEdit.h>
|
||||
#include <Command.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -293,7 +295,6 @@ Command::Command()
|
|||
_displays_id(true),
|
||||
_needs_confirm(false),
|
||||
_needs_gc(true),
|
||||
_needs_recur_update(false),
|
||||
_uses_context(false),
|
||||
_accepts_filter(false),
|
||||
_accepts_modifications(false),
|
||||
|
@ -321,9 +322,6 @@ bool Command::displays_id() const { return _displays_id; }
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Command::needs_gc() const { return _needs_gc; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Command::needs_recur_update() const { return _needs_recur_update; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Command::uses_context() const { return _uses_context; }
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Command {
|
||||
public:
|
||||
|
@ -61,7 +62,6 @@ class Command {
|
|||
bool read_only() const;
|
||||
bool displays_id() const;
|
||||
bool needs_gc() const;
|
||||
bool needs_recur_update() const;
|
||||
virtual bool uses_context() const;
|
||||
bool accepts_filter() const;
|
||||
bool accepts_modifications() const;
|
||||
|
@ -81,7 +81,6 @@ class Command {
|
|||
bool _displays_id;
|
||||
bool _needs_confirm;
|
||||
bool _needs_gc;
|
||||
bool _needs_recur_update;
|
||||
bool _uses_context;
|
||||
bool _accepts_filter;
|
||||
bool _accepts_modifications;
|
||||
|
|
|
@ -28,11 +28,13 @@
|
|||
// cmake.h include header must come first
|
||||
|
||||
#include <Context.h>
|
||||
#include <dependency.h>
|
||||
#include <format.h>
|
||||
#include <main.h>
|
||||
#include <shared.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
|
||||
#define STRING_DEPEND_BLOCKED "Task {1} is blocked by:"
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2006 - 2025, Tomas Babej, Paul Beckingham, Federico Hernandez,
|
||||
// Tobias Predel.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// https://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDED_DEPENDENCY
|
||||
#define INCLUDED_DEPENDENCY
|
||||
|
||||
#include <cmake.h>
|
||||
// cmake.h include header must come first
|
||||
|
||||
#include <Task.h>
|
||||
|
||||
#define STRING_DEPEND_BLOCKED "Task {1} is blocked by:"
|
||||
bool dependencyIsCircular(const Task& task);
|
||||
void dependencyChainOnComplete(Task& task);
|
||||
void dependencyChainOnStart(Task& task);
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue