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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af337df10c1862b3fd09a7faf3c816820e1a7709158f21fd098897771a815746
4
- data.tar.gz: 4ab0b0a8644bcf95d7bbcadc6827e37c1cbff28e3f72a5b0b0d6d0a1e0cc9aaa
3
+ metadata.gz: e01ec15c8492334e8b6722c2932bf4b39054c93d251cfd3baf18f64bb8a5cdf5
4
+ data.tar.gz: 2df70def10c1411d953300a02ac56e4d585189ee76ec3479d7fdf8b43fd05a38
5
5
  SHA512:
6
- metadata.gz: '07279b71d2b721d5906bf583ea0107072ee92f77d836221a9f26cb9a0a419d87b9190838b668cb2c04a2e23f49caddd3751880ab3d5da2cbbffe8e4f2b32c094'
7
- data.tar.gz: 54d070b62a1a529c9688b338ba920d51a4afe28b8c2ab6f9bb2ad0117c56bf59c58bb33d08336624b6d0f5124ae27ad840c54f524689bbce9e96c0c3233db575
6
+ metadata.gz: 0bf8ed1f3a1662f7dd5fbf1549e4749f3e9ed017ce39e31fae868c2a186519c609c2155a6c4b6cefc5a95cb544b89fbc64b5c8299c7c8a91a28a643e08f4a0a6
7
+ data.tar.gz: acaf8ab75fd4df5d116f70b9b20d9923de81de2363c8350649652a0ab79227694c9f6349f0b5ae412aef9e54c7928dc7845c8a7bbf0447fd603178bc1c4b155d
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.0
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
@@ -890,6 +890,7 @@ version = "0.30.1"
890
890
  source = "registry+https://github.com/rust-lang/crates.io-index"
891
891
  checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
892
892
  dependencies = [
893
+ "cc",
893
894
  "pkg-config",
894
895
  "vcpkg",
895
896
  ]
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 (2025-08-12)
5
+ ## Ruby Version Support (2026-09-10)
6
6
 
7
- This gem supports Ruby 3.2 and later. We follow Ruby's end-of-life (EOL) schedule and drop support for Ruby versions that have reached EOL.
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.2**: Supported (EOL: March 2026)
10
- - **Ruby 3.3**: Supported (Current stable)
11
- - **Ruby 3.4**: Supported
12
- - **Ruby 3.0-3.1**: Not supported (reached EOL)
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.2 or later
19
- 2. Rust toolchain (install from https://rustup.rs/)
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.
@@ -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
- taskchampion = { version = "2.0", default-features = false, features = ["server-sync", "server-gcp"] }
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
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Taskchampion
4
- VERSION = "0.9.3"
4
+ VERSION = "0.9.5"
5
5
  end
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.3
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-05-31 00:00:00.000000000 Z
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.0.0
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.4.1
102
+ rubygems_version: 3.5.22
102
103
  signing_key:
103
104
  specification_version: 4
104
105
  summary: Ruby bindings for TaskChampion