taskchampion-rb 0.5.0 → 0.6.0

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: 8b267de15e0004e931e2a46f37f9014afe8fdc52e58e675190dab990cb345e75
4
- data.tar.gz: 6a84efc5a165c428c67e6d50f3ce0b001eab4d3fde464ffed123d218aaf04033
3
+ metadata.gz: 494521791e308dacc686f45ef7ff87937a0038e46729092a4e145952971a5f56
4
+ data.tar.gz: ac3a7b7367b2d8565ac902981fb4c7a9ee45b7d0c825868b15591211debc733b
5
5
  SHA512:
6
- metadata.gz: ff860c7dcb85bc6a04aced731b403072a03c3a222f869fec0a25af1436b14fb67e4df0a9dc5cfad4d829b1fe1f39936e6df07c90605eb859202ac8f80fc8a17f
7
- data.tar.gz: d826c3704fec6432e872abe24423d92e04da810c0718ce0cc224dbddd780b2279b336c635bd1e285405bd4534710fbd9928bf4ee7c5f225f4118baade8315436
6
+ metadata.gz: 3d5c1e59e10ac46d98a8fc30d666dac904fcf2d14742c12713a16050a7a67d87c21e1a42ebaf7d25762541d0335c3c36ab2cf6a93bd3ed778046cd1a739840f4
7
+ data.tar.gz: 8f69921b628b5b1803a940584b05dd46abc854e50d9a3555646a141298a6c2a55008b2c8ca60b508fd53566bc6d0bd28a69f8caf76021e37a56e9fbf69bd362c
data/CLAUDE.md ADDED
@@ -0,0 +1,67 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Build and Development Commands
6
+
7
+ ### Building the gem
8
+ ```bash
9
+ bundle install
10
+ bundle exec rake compile # Compiles the Rust extension
11
+ ```
12
+
13
+ ### Running tests
14
+ ```bash
15
+ bundle exec rake test # Run all tests
16
+ bundle exec rake test TEST=test/test_replica.rb # Run specific test file
17
+ ```
18
+
19
+ ### Linting
20
+ ```bash
21
+ bundle exec rake rubocop # Run RuboCop linter
22
+ ```
23
+
24
+ ### Publishing new version
25
+ ```bash
26
+ rake publish[patch] # Bump patch version and release
27
+ rake publish[minor] # Bump minor version and release
28
+ rake publish[major] # Bump major version and release
29
+ ```
30
+
31
+ ## Architecture Overview
32
+
33
+ This is a Ruby gem that provides bindings to TaskChampion (Rust library) for task management. The architecture consists of:
34
+
35
+ ### Key Components
36
+
37
+ 1. **Rust Extension** (`ext/taskchampion/`)
38
+ - Written in Rust using Magnus for Ruby-Rust interop
39
+ - Entry point: `ext/taskchampion/src/lib.rs`
40
+ - Implements core classes: Replica, Task, WorkingSet, Operations, etc.
41
+ - Thread safety enforced via `thread_check.rs` - objects can only be accessed from their creation thread
42
+
43
+ 2. **Ruby Layer** (`lib/taskchampion.rb`)
44
+ - Thin wrapper that loads the Rust extension
45
+ - Extends WorkingSet and Replica classes with Ruby-specific convenience methods
46
+ - Maintains Ruby idioms (snake_case methods, `?` suffix for booleans)
47
+
48
+ 3. **Core Classes**
49
+ - `Replica`: Main database interface for task storage (in-memory or on-disk)
50
+ - `Task`: Individual task with properties and methods
51
+ - `Operations`: Collection of operations for batch changes
52
+ - `WorkingSet`: Active subset of tasks
53
+ - `DependencyMap`: Task dependency management
54
+ - Error hierarchy: Error → ThreadError, StorageError, ValidationError, ConfigError
55
+
56
+ ### Testing Structure
57
+ - Uses Minitest framework
58
+ - Tests organized in `test/unit/`, `test/integration/`, and `test/performance/`
59
+ - Base test class: `TaskchampionTest` in `test/test_helper.rb`
60
+ - Tests use temporary directories for file-based replicas
61
+
62
+ ### Ruby API Design Principles
63
+ - Methods use snake_case (not get_/set_ prefixes)
64
+ - Boolean methods end with `?`
65
+ - Symbols for enums (`:pending`, `:completed`, `:read_only`)
66
+ - `nil` instead of None
67
+ - Keyword arguments for optional parameters
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'taskchampion'
5
+ require 'securerandom'
6
+
7
+ # Create an in-memory replica
8
+ replica = Taskchampion::Replica.new_in_memory
9
+
10
+ # Create several tasks with different statuses
11
+ puts "Creating tasks..."
12
+
13
+ # Create pending tasks
14
+ 3.times do |i|
15
+ ops = Taskchampion::Operations.new
16
+ task = replica.create_task(SecureRandom.uuid, ops)
17
+ task.set_description("Pending task #{i + 1}", ops)
18
+ task.set_status(Taskchampion::PENDING, ops)
19
+ replica.commit_operations(ops)
20
+ puts " Created pending task: #{task.description}"
21
+ end
22
+
23
+ # Create completed tasks
24
+ 2.times do |i|
25
+ ops = Taskchampion::Operations.new
26
+ task = replica.create_task(SecureRandom.uuid, ops)
27
+ task.set_description("Completed task #{i + 1}", ops)
28
+ task.set_status(Taskchampion::COMPLETED, ops)
29
+ replica.commit_operations(ops)
30
+ puts " Created completed task: #{task.description}"
31
+ end
32
+
33
+ # Create a deleted task
34
+ ops = Taskchampion::Operations.new
35
+ task = replica.create_task(SecureRandom.uuid, ops)
36
+ task.set_description("Deleted task", ops)
37
+ task.set_status(Taskchampion::DELETED, ops)
38
+ replica.commit_operations(ops)
39
+ puts " Created deleted task: #{task.description}"
40
+
41
+ puts "\n" + "=" * 50
42
+ puts "Getting pending tasks..."
43
+ puts "=" * 50
44
+
45
+ # Use the pending_tasks method to get only pending tasks
46
+ pending = replica.pending_tasks
47
+
48
+ puts "\nFound #{pending.length} pending tasks:"
49
+ pending.each_with_index do |task, index|
50
+ puts " #{index + 1}. [#{task.uuid[0..7]}...] #{task.description}"
51
+ puts " Status: #{task.status}"
52
+ puts " Active: #{task.active?}"
53
+ end
54
+
55
+ puts "\n" + "=" * 50
56
+ puts "For comparison, all_tasks returns #{replica.all_tasks.size} tasks total"
@@ -260,6 +260,20 @@ impl Replica {
260
260
 
261
261
  Ok(tc_replica.num_undo_points().map_err(into_error)?)
262
262
  }
263
+
264
+ fn pending_tasks(&self) -> Result<RArray, Error> {
265
+ let mut tc_replica = self.0.get_mut()?;
266
+
267
+ let tc_tasks = tc_replica.pending_tasks().map_err(into_error)?;
268
+
269
+ let array = RArray::new();
270
+ for tc_task in tc_tasks {
271
+ let ruby_task = crate::task::Task::from_tc_task(tc_task);
272
+ array.push(ruby_task)?;
273
+ }
274
+
275
+ Ok(array)
276
+ }
263
277
  }
264
278
 
265
279
  pub fn init(module: &RModule) -> Result<(), Error> {
@@ -285,6 +299,7 @@ pub fn init(module: &RModule) -> Result<(), Error> {
285
299
  class.define_method("expire_tasks", method!(Replica::expire_tasks, 0))?;
286
300
  class.define_method("num_local_operations", method!(Replica::num_local_operations, 0))?;
287
301
  class.define_method("num_undo_points", method!(Replica::num_undo_points, 0))?;
302
+ class.define_method("pending_tasks", method!(Replica::pending_tasks, 0))?;
288
303
 
289
304
  Ok(())
290
305
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Taskchampion
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taskchampion-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Case
@@ -36,6 +36,7 @@ files:
36
36
  - ".rubocop.yml"
37
37
  - ".ruby-version"
38
38
  - CHANGELOG.md
39
+ - CLAUDE.md
39
40
  - Cargo.lock
40
41
  - Cargo.toml
41
42
  - README.md
@@ -48,6 +49,7 @@ files:
48
49
  - docs/plan.md
49
50
  - example.md
50
51
  - examples/basic_usage.rb
52
+ - examples/pending_tasks.rb
51
53
  - examples/sync_workflow.rb
52
54
  - ext/taskchampion/Cargo.toml
53
55
  - ext/taskchampion/extconf.rb