diff --git a/features/steps/ticket_steps.py b/features/steps/ticket_steps.py index 276eb278..6ba443d5 100644 --- a/features/steps/ticket_steps.py +++ b/features/steps/ticket_steps.py @@ -27,7 +27,7 @@ def get_ticket_script(context): return str(Path(context.project_dir) / 'ticket') -def create_ticket(context, ticket_id, title, priority=2, parent=None): +def create_ticket(context, ticket_id, title, typ='task', priority=2, parent=None): """Helper to create a ticket file.""" tickets_dir = Path(context.test_dir) / '.tickets' tickets_dir.mkdir(parents=True, exist_ok=True) @@ -39,7 +39,7 @@ def create_ticket(context, ticket_id, title, priority=2, parent=None): deps: [] links: [] created: 2024-01-01T00:00:00Z -type: task +type: {typ} priority: {priority} ''' if parent: @@ -92,6 +92,12 @@ def step_ticket_exists_with_parent(context, ticket_id, title, parent_id): create_ticket(context, ticket_id, title, parent=parent_id) +@given(r'a ticket exists with ID "(?P[^"]+)" and title "(?P[^"]+)" with type "(?P<typ>[^"]+)"') +def step_ticket_exists_with_type(context, ticket_id, title, typ): + """Create a ticket with given ID, title, and type.""" + create_ticket(context, ticket_id, title, typ=typ) + + @given(r'a ticket exists with ID "(?P<ticket_id>[^"]+)" and title "(?P<title>[^"]+)"') def step_ticket_exists(context, ticket_id, title): """Create a ticket with given ID and title (basic, no extra params).""" diff --git a/features/ticket_listing.feature b/features/ticket_listing.feature index 7c78852d..0ae28e13 100644 --- a/features/ticket_listing.feature +++ b/features/ticket_listing.feature @@ -26,6 +26,16 @@ Feature: Ticket Listing Then the command should succeed And the output should match pattern "list-0001\s+\[open\]\s+-\s+My ticket" + Scenario: List with ticket type filter + Given a ticket exists with ID "list-0001" and title "First" with type "epic" + And a ticket exists with ID "list-0002" and title "Second" with type "task" + And a ticket exists with ID "list-0003" and title "Third" with type "epic" + When I run "ticket ls -t epic" + Then the command should succeed + And the output should contain "list-0001" + And the output should not contain "list-0002" + And the output should contain "list-0003" + Scenario: List with status filter Given a ticket exists with ID "list-0001" and title "Open ticket" And a ticket exists with ID "list-0002" and title "Closed ticket" diff --git a/ticket b/ticket index 342678ec..f188094c 100755 --- a/ticket +++ b/ticket @@ -651,7 +651,7 @@ cmd_dep() { } cmd_ls() { - local status_filter="" assignee_filter="" tag_filter="" + local status_filter="" assignee_filter="" tag_filter="" type_filter="" while [[ $# -gt 0 ]]; do case "$1" in --status=*) status_filter="${1#--status=}"; shift ;; @@ -659,11 +659,17 @@ cmd_ls() { --assignee=*) assignee_filter="${1#--assignee=}"; shift ;; -T) tag_filter="$2"; shift 2 ;; --tag=*) tag_filter="${1#--tag=}"; shift ;; + -t) type_filter="$2"; shift 2 ;; + --type=*) type_filter="${1#--type=}"; shift ;; *) shift ;; esac done - awk -v status_filter="$status_filter" -v assignee_filter="$assignee_filter" -v tag_filter="$tag_filter" ' + awk -v status_filter="$status_filter" \ + -v assignee_filter="$assignee_filter" \ + -v tag_filter="$tag_filter" \ + -v type_filter="$type_filter" \ + ' BEGIN { FS=": "; in_front=0 } FNR==1 { if (prev_file) emit() @@ -672,6 +678,7 @@ cmd_ls() { } /^---$/ { in_front = !in_front; next } in_front && /^id:/ { id = $2 } + in_front && /^type:/ { type = $2 } in_front && /^status:/ { status = $2 } in_front && /^assignee:/ { assignee = $2 } in_front && /^tags:/ { tags = $2; gsub(/[\[\] ]/, "", tags) } @@ -687,7 +694,12 @@ cmd_ls() { return 0 } function emit() { - if (id != "" && (status_filter == "" || status == status_filter) && (assignee_filter == "" || assignee == assignee_filter) && (tag_filter == "" || has_tag(tags, tag_filter))) { + if (id != "" \ + && (status_filter == "" || status == status_filter) \ + && (assignee_filter == "" || assignee == assignee_filter) \ + && (tag_filter == "" || has_tag(tags, tag_filter)) \ + && (type_filter == "" || type == type_filter)) + { deps_display = (deps != "") ? "[" deps "]" : "[]" gsub(/,/, ", ", deps_display) dep_str = (deps_display != "[]") ? " <- " deps_display : "" @@ -1460,7 +1472,7 @@ Commands: undep <id> <dep-id> Remove dependency link <id> <id> [id...] Link tickets together (symmetric) unlink <id> <target-id> Remove link between tickets - ls|list [--status=X] [-a X] [-T X] List tickets + ls|list [--status=X] [-a X] [-T X] [-t X] List tickets ready [-a X] [-T X] List open/in-progress tickets with deps resolved blocked [-a X] [-T X] List open/in-progress tickets with unresolved deps closed [--limit=N] [-a X] [-T X] List recently closed tickets (default 20, by mtime)