taskchampion-rb 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +77 -0
- data/Cargo.lock +1 -0
- data/README.md +16 -8
- data/docs/post_upstream_fix_migration.md +147 -0
- data/ext/taskchampion/Cargo.toml +3 -1
- data/ext/taskchampion/src/error.rs +4 -0
- data/lib/taskchampion/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e01ec15c8492334e8b6722c2932bf4b39054c93d251cfd3baf18f64bb8a5cdf5
|
|
4
|
+
data.tar.gz: 2df70def10c1411d953300a02ac56e4d585189ee76ec3479d7fdf8b43fd05a38
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bf8ed1f3a1662f7dd5fbf1549e4749f3e9ed017ce39e31fae868c2a186519c609c2155a6c4b6cefc5a95cb544b89fbc64b5c8299c7c8a91a28a643e08f4a0a6
|
|
7
|
+
data.tar.gz: acaf8ab75fd4df5d116f70b9b20d9923de81de2363c8350649652a0ab79227694c9f6349f0b5ae412aef9e54c7928dc7845c8a7bbf0447fd603178bc1c4b155d
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.3.9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,82 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
- Drop support for Ruby 3.2 (reached EOL March 2026). Minimum supported
|
|
4
|
+
Ruby is now 3.3; CI tests 3.3, 3.4, and 3.5.
|
|
5
|
+
- Enable the `bundled` feature of the `taskchampion` crate so SQLite is
|
|
6
|
+
compiled from source into the extension. Previously `default-features
|
|
7
|
+
= false` dropped `bundled`, making the build link against system
|
|
8
|
+
SQLite and fail with `cannot find -lsqlite3` on any host without
|
|
9
|
+
`libsqlite3-dev` installed.
|
|
10
|
+
- Expand README build prerequisites: `clang`/`libclang-dev` (needed by
|
|
11
|
+
`rb-sys` bindgen) on Linux, `xcode-select --install` on macOS, and
|
|
12
|
+
note that the Rust toolchain is optional since `rb-sys` bootstraps
|
|
13
|
+
one.
|
|
14
|
+
|
|
15
|
+
## [0.9.4] - 2026-07-11
|
|
16
|
+
|
|
17
|
+
- Include the full cause chain in sync error messages. TaskChampion
|
|
18
|
+
wraps sync failures in an anyhow context, and the default `Display`
|
|
19
|
+
previously printed only the outermost line ("Failed to synchronize
|
|
20
|
+
with server"), hiding the real cause. `Error::Other` is now formatted
|
|
21
|
+
with anyhow's alternate format so the full chain (HTTP status,
|
|
22
|
+
connection errors, server rejections) reaches Ruby.
|
|
23
|
+
- Add `server-gcp` feature flag, required for `ServerConfig::Gcp` used
|
|
24
|
+
by `sync_gcp`
|
|
25
|
+
- Fix order-dependent annotation test
|
|
26
|
+
|
|
27
|
+
## [0.9.3] - 2026-05-30
|
|
28
|
+
|
|
29
|
+
- Add `Task#set_modified` method, consistent with `set_entry`
|
|
30
|
+
- Move docs
|
|
31
|
+
- Change taskchampion dependency to enable `server-sync` feature
|
|
32
|
+
|
|
33
|
+
## [0.9.2] - 2026-05-22
|
|
34
|
+
|
|
35
|
+
- Fix all Rust compiler warnings
|
|
36
|
+
|
|
37
|
+
## [0.9.1] - 2026-05-22
|
|
38
|
+
|
|
39
|
+
- Fix error mapping to use `taskchampion::Error` enum variants instead
|
|
40
|
+
of heuristic message-content matching. Adds
|
|
41
|
+
`Taskchampion::OutOfSyncError < SyncError` for the `OutOfSync`
|
|
42
|
+
sentinel, signaling an irrecoverable divergence that requires a full
|
|
43
|
+
re-sync rather than a retry
|
|
44
|
+
|
|
45
|
+
## [0.9.0] - 2025-10-17
|
|
46
|
+
|
|
47
|
+
- Add remove and update annotations support
|
|
48
|
+
|
|
49
|
+
## [0.8.0] - 2025-09-24
|
|
50
|
+
|
|
51
|
+
- Add undo/history functionality with operation tracking
|
|
52
|
+
- Add `set_timestamp` and `get_timestamp` methods for custom date
|
|
53
|
+
fields
|
|
54
|
+
- Fix RuboCop errors
|
|
55
|
+
|
|
56
|
+
## [0.7.0] - 2025-08-18
|
|
57
|
+
|
|
58
|
+
- Add `set_entry` method to `Task`
|
|
59
|
+
- Fix RuboCop errors
|
|
60
|
+
|
|
61
|
+
## [0.6.0] - 2025-08-14
|
|
62
|
+
|
|
63
|
+
- Add pending task support to `Replica`
|
|
64
|
+
|
|
65
|
+
## [0.5.0] - 2025-08-14
|
|
66
|
+
|
|
67
|
+
- Implement `done` status handling
|
|
68
|
+
|
|
69
|
+
Note: v0.4.0 was tagged against the same commit as v0.5.0 and carries
|
|
70
|
+
no distinct changes; treat v0.5.0 as its replacement.
|
|
71
|
+
|
|
72
|
+
## [0.3.0] - 2025-08-14
|
|
73
|
+
|
|
74
|
+
- Rename gem to `taskchampion-rb`
|
|
75
|
+
- Implement `TaskData`
|
|
76
|
+
- Rename `tasks` to `all_tasks`
|
|
77
|
+
- Support Windows and ARM builds
|
|
78
|
+
- Drop support for Ruby versions below 3.2
|
|
79
|
+
|
|
3
80
|
## [0.2.0] - 2025-08-11
|
|
4
81
|
|
|
5
82
|
- Enhanced error handling with contextual messages
|
data/Cargo.lock
CHANGED
data/README.md
CHANGED
|
@@ -2,26 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
Ruby bindings for TaskChampion, the task database that powers Taskwarrior.
|
|
4
4
|
|
|
5
|
-
## Ruby Version Support (
|
|
5
|
+
## Ruby Version Support (2026-09-10)
|
|
6
6
|
|
|
7
|
-
This gem supports Ruby 3.
|
|
7
|
+
This gem supports Ruby 3.3 and later. We follow Ruby's end-of-life (EOL) schedule and drop support for Ruby versions that have reached EOL.
|
|
8
8
|
|
|
9
|
-
- **Ruby 3.
|
|
10
|
-
- **Ruby 3.
|
|
11
|
-
- **Ruby 3.
|
|
12
|
-
- **Ruby 3.0-3.
|
|
9
|
+
- **Ruby 3.3**: Supported
|
|
10
|
+
- **Ruby 3.4**: Supported (Current stable)
|
|
11
|
+
- **Ruby 3.5**: Supported
|
|
12
|
+
- **Ruby 3.0-3.2**: Not supported (reached EOL)
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
16
|
### Prerequisites
|
|
17
17
|
|
|
18
|
-
1. Ruby 3.
|
|
19
|
-
2.
|
|
18
|
+
1. Ruby 3.3 or later
|
|
19
|
+
2. A C compiler and `clang`/`libclang` development headers — `rb-sys` runs
|
|
20
|
+
libclang over Ruby's headers to generate FFI bindings during `rake compile`.
|
|
21
|
+
- **Debian/Ubuntu:** `sudo apt install clang libclang-dev`
|
|
22
|
+
- **macOS:** `xcode-select --install`
|
|
23
|
+
3. Rust toolchain (optional — if `cargo` is not found, `rb-sys` bootstraps its
|
|
24
|
+
own rustup + toolchain during the build). To install it yourself:
|
|
20
25
|
|
|
21
26
|
```bash
|
|
22
27
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
23
28
|
```
|
|
24
29
|
|
|
30
|
+
> SQLite is compiled from source into the extension (the `bundled` feature), so
|
|
31
|
+
> no system SQLite / `libsqlite3-dev` is required.
|
|
32
|
+
|
|
25
33
|
### Building from source
|
|
26
34
|
|
|
27
35
|
```bash
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Migration plan: once the upstream `taskchampion` sync-error fix lands
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
`Replica::sync()` in the upstream `taskchampion` crate currently routes
|
|
6
|
+
every sync failure through `anyhow::Context`, which erases the typed
|
|
7
|
+
`Error` variant (`Database`, `Server`, `OutOfSync`, `Usage`) and
|
|
8
|
+
re-boxes it as the catch-all `Error::Other` — regardless of what
|
|
9
|
+
actually failed. See `upstream_issue_draft.md` at the root of this
|
|
10
|
+
checkout of `~/Sites/reference/taskchampion` for the full writeup filed
|
|
11
|
+
against `GothenburgBitFactory/taskchampion`.
|
|
12
|
+
|
|
13
|
+
This document tracks what changes in `taskchampion-rb` once that
|
|
14
|
+
upstream issue is fixed and released (or once we point at a patched
|
|
15
|
+
fork, whichever comes first).
|
|
16
|
+
|
|
17
|
+
## What does *not* need to change
|
|
18
|
+
|
|
19
|
+
`ext/taskchampion/src/error.rs`'s `map_taskchampion_error` already has
|
|
20
|
+
the correct match arms:
|
|
21
|
+
|
|
22
|
+
```rust
|
|
23
|
+
match error {
|
|
24
|
+
Error::Database(msg) => Error::new(storage_error(), msg),
|
|
25
|
+
Error::Server(msg) => Error::new(sync_error(), msg),
|
|
26
|
+
Error::OutOfSync => Error::new(out_of_sync_error(), "..."),
|
|
27
|
+
Error::Usage(msg) => Error::new(validation_error(), msg),
|
|
28
|
+
Error::Other(err) => Error::new(storage_error(), format!("{err:#}")),
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
These arms have been correct since `0.9.1` ("Fix error mapping to use
|
|
33
|
+
enum variants") — they've simply been dead code for sync failures
|
|
34
|
+
specifically, because `Replica::sync()` never handed them a real
|
|
35
|
+
`Server`/`OutOfSync` value to match against. No changes needed here.
|
|
36
|
+
|
|
37
|
+
## What does need to change
|
|
38
|
+
|
|
39
|
+
### 1. Bump the pinned crate dependency
|
|
40
|
+
|
|
41
|
+
`ext/taskchampion/Cargo.toml`:
|
|
42
|
+
|
|
43
|
+
```toml
|
|
44
|
+
taskchampion = { version = "2.0", default-features = false, features = ["server-sync", "server-gcp"] }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Once the fix ships in a crates.io release, bump `"2.0"` to whatever
|
|
48
|
+
version includes it. If we go the fork route first (patch applied
|
|
49
|
+
locally, upstream PR still pending review), point at the fork instead:
|
|
50
|
+
|
|
51
|
+
```toml
|
|
52
|
+
taskchampion = { git = "https://github.com/<you>/taskchampion", branch = "preserve-sync-error-variant", default-features = false, features = ["server-sync", "server-gcp"] }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Swap back to the crates.io version once/if the PR merges and releases.
|
|
56
|
+
|
|
57
|
+
Run `cargo update -p taskchampion` (or `bundle exec rake compile`,
|
|
58
|
+
which will pull in the new `Cargo.lock` resolution) and recompile.
|
|
59
|
+
|
|
60
|
+
### 2. This is a breaking change for consumers — bump to 0.10.0
|
|
61
|
+
|
|
62
|
+
`Taskchampion::StorageError` and `Taskchampion::SyncError` are
|
|
63
|
+
**siblings** under `Taskchampion::Error`, not superclass/subclass:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Taskchampion::Error
|
|
67
|
+
├── Taskchampion::StorageError
|
|
68
|
+
└── Taskchampion::SyncError
|
|
69
|
+
└── Taskchampion::OutOfSyncError
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Today, every `sync_to_remote`/`sync_to_local`/`sync_to_gcp` failure
|
|
73
|
+
raises `StorageError`. After this fix, connection/network/out-of-sync
|
|
74
|
+
failures will raise `SyncError` or `OutOfSyncError` instead. Any
|
|
75
|
+
consumer code doing `rescue Taskchampion::StorageError` specifically
|
|
76
|
+
around a sync call — expecting it to catch sync failures — will
|
|
77
|
+
silently stop catching them.
|
|
78
|
+
|
|
79
|
+
Per semver for a pre-1.0 gem, this warrants a **minor** version bump
|
|
80
|
+
(`0.9.4` → `0.10.0`), not a jump to `1.0.0`. See the CHANGELOG entry
|
|
81
|
+
below.
|
|
82
|
+
|
|
83
|
+
### 3. Update `docs/TaskchampionRbErrors.md`
|
|
84
|
+
|
|
85
|
+
This file already documents `SyncError`/`OutOfSyncError` as reachable
|
|
86
|
+
via `Error::Server`/`Error::OutOfSync` — that documentation is
|
|
87
|
+
currently aspirational/inaccurate for sync failures specifically. Once
|
|
88
|
+
the fix lands, it becomes correct; no wording changes should be
|
|
89
|
+
needed, but re-verify the examples still match actual raised messages
|
|
90
|
+
(the message text may shift slightly depending on how the upstream fix
|
|
91
|
+
formats the wrapped context — see caveat below).
|
|
92
|
+
|
|
93
|
+
### 4. Verify existing tests still pass, add classification coverage
|
|
94
|
+
|
|
95
|
+
Existing tests are already forward-compatible:
|
|
96
|
+
|
|
97
|
+
- `test/integration/test_sync_operations.rb:150`
|
|
98
|
+
(`test_sync_error_handling`) asserts
|
|
99
|
+
`Taskchampion::StorageError, Taskchampion::SyncError` (either) — no
|
|
100
|
+
change needed.
|
|
101
|
+
- `test/integration/test_sync_operations.rb`
|
|
102
|
+
(`test_remote_sync_error_includes_underlying_cause`, added in
|
|
103
|
+
`61130f5`) asserts the base `Taskchampion::Error` and matches on
|
|
104
|
+
message content — no change needed, but re-run it: the exact message
|
|
105
|
+
format may shift if the upstream fix wraps the inner message
|
|
106
|
+
differently than our expectation
|
|
107
|
+
(`"Failed to synchronize with server: <cause>"`).
|
|
108
|
+
|
|
109
|
+
Add new coverage once the fix lands:
|
|
110
|
+
|
|
111
|
+
- A test that a genuinely out-of-sync replica (server has diverged,
|
|
112
|
+
e.g. by resetting the sync server's storage under a replica that has
|
|
113
|
+
already synced) raises `Taskchampion::OutOfSyncError` specifically,
|
|
114
|
+
not just `StorageError`/`SyncError`.
|
|
115
|
+
- A test that a connection failure (as in the existing
|
|
116
|
+
`test_remote_sync_error_includes_underlying_cause`) raises
|
|
117
|
+
`Taskchampion::SyncError` specifically, not `StorageError`.
|
|
118
|
+
|
|
119
|
+
### 5. CHANGELOG entry
|
|
120
|
+
|
|
121
|
+
Add to `[Unreleased]` (or a new `[0.10.0]` section once released):
|
|
122
|
+
|
|
123
|
+
```markdown
|
|
124
|
+
## [0.10.0] - YYYY-MM-DD
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
- **Breaking:** sync failures now raise `Taskchampion::SyncError` or
|
|
128
|
+
`Taskchampion::OutOfSyncError` instead of `Taskchampion::StorageError`,
|
|
129
|
+
now that upstream `taskchampion` preserves the typed error variant
|
|
130
|
+
through `Replica::sync()` instead of erasing it via `anyhow::Context`.
|
|
131
|
+
Code that rescues `Taskchampion::StorageError` specifically around a
|
|
132
|
+
sync call should rescue `Taskchampion::SyncError` (or the common
|
|
133
|
+
base `Taskchampion::Error`) instead.
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Downstream: bravo / wt_engine
|
|
137
|
+
|
|
138
|
+
Once `taskchampion-rb` is bumped in `bravo`'s and `wt_engine`'s
|
|
139
|
+
`Gemfile.lock`, `Wt::SyncEventProcessor`'s failure path
|
|
140
|
+
(`engines/wt_engine/app/jobs/wt/sync_event_processor.rb`) and
|
|
141
|
+
`Tc::Sync#with_rescue` (`engines/wt_engine/app/services/tc/sync.rb`)
|
|
142
|
+
both use bare `rescue => e` / catch any `StandardError`, so they are
|
|
143
|
+
unaffected by the exception-class change — no code changes required
|
|
144
|
+
there. The benefit is purely in Sentry: `Taskchampion::OutOfSyncError`
|
|
145
|
+
and `Taskchampion::SyncError` will appear as distinct issues/fingerprints
|
|
146
|
+
instead of one generic `StorageError` bucket, without needing any
|
|
147
|
+
message-string parsing to distinguish them.
|
data/ext/taskchampion/Cargo.toml
CHANGED
|
@@ -12,7 +12,9 @@ crate-type = ["cdylib"]
|
|
|
12
12
|
[dependencies]
|
|
13
13
|
magnus = { version = "0.7", features = ["rb-sys"] }
|
|
14
14
|
rb-sys = "0.9.103"
|
|
15
|
-
|
|
15
|
+
# `bundled` compiles SQLite from source into the extension so the build does not
|
|
16
|
+
# depend on the host having libsqlite3-dev / a compatible system SQLite.
|
|
17
|
+
taskchampion = { version = "2.0", default-features = false, features = ["bundled", "server-sync", "server-gcp"] }
|
|
16
18
|
chrono = "0.4"
|
|
17
19
|
uuid = "1.0"
|
|
18
20
|
|
|
@@ -58,6 +58,10 @@ pub fn map_taskchampion_error(error: taskchampion::Error) -> Error {
|
|
|
58
58
|
taskchampion::Error::OutOfSync => Error::new(out_of_sync_error(),
|
|
59
59
|
"Local replica is out of sync with the server"),
|
|
60
60
|
taskchampion::Error::Usage(msg) => Error::new(validation_error(), msg),
|
|
61
|
+
// anyhow's alternate format renders the full cause chain
|
|
62
|
+
// ("context: cause: root cause"), not just the top context line.
|
|
63
|
+
taskchampion::Error::Other(err) => Error::new(storage_error(),
|
|
64
|
+
format!("{err:#}")),
|
|
61
65
|
_ => Error::new(storage_error(), error.to_string()),
|
|
62
66
|
}
|
|
63
67
|
}
|
data/lib/taskchampion/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: taskchampion-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Case
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|
|
@@ -51,6 +51,7 @@ files:
|
|
|
51
51
|
- docs/errors.md
|
|
52
52
|
- docs/phase_3_plan.md
|
|
53
53
|
- docs/plan.md
|
|
54
|
+
- docs/post_upstream_fix_migration.md
|
|
54
55
|
- example.md
|
|
55
56
|
- examples/basic_usage.rb
|
|
56
57
|
- examples/pending_tasks.rb
|
|
@@ -91,14 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
91
92
|
requirements:
|
|
92
93
|
- - ">="
|
|
93
94
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: 3.
|
|
95
|
+
version: 3.3.0
|
|
95
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
97
|
requirements:
|
|
97
98
|
- - ">="
|
|
98
99
|
- !ruby/object:Gem::Version
|
|
99
100
|
version: 3.3.11
|
|
100
101
|
requirements: []
|
|
101
|
-
rubygems_version: 3.
|
|
102
|
+
rubygems_version: 3.5.22
|
|
102
103
|
signing_key:
|
|
103
104
|
specification_version: 4
|
|
104
105
|
summary: Ruby bindings for TaskChampion
|