Skip to content

Commit 8c5dfc4

Browse files
committed
📝 docs(maniphest): Add advanced project filtering documentation
Enhance project search documentation with comprehensive guide on advanced project filtering using AND/OR logic and wildcard patterns. - Add detailed explanation of project search syntax - Include multiple examples of complex project filtering - Demonstrate use cases for cross-team and cross-project searches - Improve CLI documentation with more precise project pattern descriptions - Refactor and expand project search documentation
1 parent 8e7056e commit 8c5dfc4

File tree

6 files changed

+1046
-36
lines changed

6 files changed

+1046
-36
lines changed

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Phabfive currently supports the following Phabricator/Phorge applications:
1010
- **Diffusion** - List repositories, get branches, clone URIs, add repositories, manage URIs
1111
- **Paste** - List, get, and add code pastes
1212
- **User** - Get information about the logged-in user
13-
- **Maniphest** - Add comments, show task details, create tasks from templates, and search with advanced transition filtering
13+
- **Maniphest** - Add comments, show task details, create tasks from templates, and search with advanced project filtering and transition filtering
1414

1515
## Getting Started
1616

docs/maniphest-cli.md

Lines changed: 194 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ phabfive maniphest create tasks.yaml --dry-run
7373

7474
## Task Search
7575

76-
Search for tasks within projects with various filtering options.
76+
Search for tasks within projects with various filtering options, including advanced project pattern matching with AND/OR logic.
7777

7878
### Basic Search
7979

@@ -83,8 +83,17 @@ phabfive maniphest search "My Project"
8383

8484
# Search all projects
8585
phabfive maniphest search "*"
86+
87+
# Search multiple projects (OR logic)
88+
phabfive maniphest search "ProjectA,ProjectB"
89+
90+
# Search project intersection (AND logic)
91+
phabfive maniphest search "Team Alpha+Sprint 42"
8692
```
8793

94+
!!! tip
95+
For advanced project filtering with AND/OR logic and complex patterns, see the [Advanced Project Filtering](#advanced-project-filtering) section below.
96+
8897
### Wildcard Project Matching
8998

9099
The project name supports wildcard patterns:
@@ -103,6 +112,189 @@ phabfive maniphest search "*API*"
103112
!!! note
104113
Project matching is case-insensitive. If no exact match is found, phabfive will suggest similar project names.
105114

115+
### Advanced Project Filtering
116+
117+
Search for tasks that belong to multiple projects using AND/OR logic. This powerful feature allows you to find tasks at the intersection of different project scopes or combine results from multiple project queries.
118+
119+
#### Pattern Syntax
120+
121+
Project patterns use a query language with AND/OR logic:
122+
123+
- **Comma (`,`)** = OR logic - match tasks in ANY of the projects
124+
- **Plus (`+`)** = AND logic - match tasks in ALL specified projects
125+
- **Wildcards (`*`)** can be combined with AND/OR operators
126+
127+
#### OR Logic Examples
128+
129+
Find tasks that belong to ANY of the specified projects:
130+
131+
```bash
132+
# Tasks in EITHER ProjectA OR ProjectB
133+
phabfive maniphest search "ProjectA,ProjectB"
134+
135+
# Tasks in any Backend project OR any Frontend project
136+
phabfive maniphest search "Backend*,Frontend*"
137+
138+
# Tasks in ProjectA OR ProjectB OR ProjectC
139+
phabfive maniphest search "ProjectA,ProjectB,ProjectC"
140+
```
141+
142+
**Use case**: Finding all tasks across multiple related projects or teams.
143+
144+
#### AND Logic Examples
145+
146+
Find tasks that belong to ALL specified projects simultaneously:
147+
148+
```bash
149+
# Tasks that are in BOTH ProjectA AND ProjectB
150+
phabfive maniphest search "ProjectA+ProjectB"
151+
152+
# Tasks tagged with both a team and a sprint
153+
phabfive maniphest search "Backend Team+Sprint 42"
154+
155+
# Tasks in multiple categories
156+
phabfive maniphest search "Security+High Priority+Q1 2024"
157+
```
158+
159+
**Use case**: Finding tasks at the intersection of multiple categorizations (e.g., tasks that belong to both a team project and a sprint milestone).
160+
161+
#### Complex Combinations
162+
163+
Combine OR and AND logic for sophisticated queries:
164+
165+
```bash
166+
# Tasks that are in (ProjectA AND ProjectB) OR (ProjectC)
167+
phabfive maniphest search "ProjectA+ProjectB,ProjectC"
168+
169+
# Tasks in (Backend Team AND Sprint 42) OR (Frontend Team AND Sprint 42)
170+
phabfive maniphest search "Backend Team+Sprint 42,Frontend Team+Sprint 42"
171+
172+
# Tasks in any Q1 project AND tagged as urgent, OR any Q2 project
173+
phabfive maniphest search "Q1*+Urgent,Q2*"
174+
```
175+
176+
**How it works**: Comma-separated groups are evaluated independently (OR), and within each group, plus-separated projects must all match (AND).
177+
178+
#### Wildcards with AND/OR Logic
179+
180+
Combine wildcard patterns with logical operators:
181+
182+
```bash
183+
# Tasks in any Backend project OR any API project
184+
phabfive maniphest search "Backend*,API*"
185+
186+
# Tasks in both a Backend project AND marked as Security
187+
phabfive maniphest search "Backend*+Security"
188+
189+
# Tasks in (any 2024 project AND High Priority) OR (any Archive project)
190+
phabfive maniphest search "*2024+High Priority,Archive*"
191+
```
192+
193+
#### Projects with Spaces
194+
195+
Project names containing spaces are fully supported:
196+
197+
```bash
198+
# Single project with spaces
199+
phabfive maniphest search "My Project"
200+
201+
# OR logic with spaces
202+
phabfive maniphest search "Project A,Project B"
203+
204+
# AND logic with spaces
205+
phabfive maniphest search "Backend Team+Sprint 42"
206+
207+
# Complex pattern with spaces
208+
phabfive maniphest search "Q1 2024+Backend Team,Q1 2024+Frontend Team"
209+
```
210+
211+
#### Real-World Examples
212+
213+
**Sprint Planning**: Find all tasks for a specific sprint across multiple teams:
214+
```bash
215+
phabfive maniphest search "Backend+Sprint 15,Frontend+Sprint 15,QA+Sprint 15"
216+
```
217+
218+
**Cross-Team Features**: Find tasks that involve multiple teams:
219+
```bash
220+
phabfive maniphest search "Backend Team+Mobile Team"
221+
```
222+
223+
**Security Audits**: Find security tasks across all product areas:
224+
```bash
225+
phabfive maniphest search "Product*+Security"
226+
```
227+
228+
**Quarterly Planning**: Find all high-priority tasks for Q1 across teams:
229+
```bash
230+
phabfive maniphest search "Q1 2024+High Priority"
231+
```
232+
233+
**Release Tracking**: Find tasks for a specific release across components:
234+
```bash
235+
phabfive maniphest search "Release 2.0+API,Release 2.0+UI,Release 2.0+Database"
236+
```
237+
238+
#### Combining with Other Filters
239+
240+
Project patterns work seamlessly with other search filters:
241+
242+
```bash
243+
# Recent tasks in multiple projects
244+
phabfive maniphest search "ProjectA,ProjectB" --updated-after=7
245+
246+
# Tasks in both team and sprint, currently in specific column
247+
phabfive maniphest search "Backend+Sprint 42" --column="in:In Progress"
248+
249+
# High-priority tasks across backend services
250+
phabfive maniphest search "Backend*" --priority="in:High"
251+
252+
# Tasks at intersection of team and milestone, recently completed
253+
phabfive maniphest search "API Team+Milestone 3" \
254+
--column="to:Done" \
255+
--updated-after=14
256+
257+
# Security tasks across products that moved backward
258+
phabfive maniphest search "Product*+Security" \
259+
--column=backward \
260+
--show-history
261+
```
262+
263+
#### Tips for Project Filtering
264+
265+
**Pattern Evaluation**:
266+
- OR patterns (comma-separated) are evaluated left to right - tasks matching ANY pattern are included
267+
- AND patterns (plus-separated) require the task to belong to ALL specified projects
268+
- Empty strings (`""`) return no results - use `"*"` to search all projects instead
269+
270+
**Performance Considerations**:
271+
- Specific project names are faster than wildcards
272+
- Wildcards like `"*"` (all projects) may take longer for large instances
273+
- Combine with date filters (`--created-after`, `--updated-after`) to narrow results
274+
275+
**Debugging Patterns**:
276+
If a pattern doesn't return expected results:
277+
278+
1. Test each project name individually first
279+
2. Verify project names match exactly (check for typos, extra spaces)
280+
3. Remember that AND logic requires tasks to be in ALL projects simultaneously
281+
4. Use `phabfive maniphest search "*"` to see all available tasks and their projects
282+
283+
**Common Patterns**:
284+
```bash
285+
# Multiple teams working on same feature
286+
"Team A+Feature X,Team B+Feature X"
287+
288+
# All projects in a category
289+
"Backend*,Frontend*,Mobile*"
290+
291+
# Specific sprint across teams
292+
"Sprint 42+Backend,Sprint 42+Frontend,Sprint 42+QA"
293+
294+
# Cross-functional initiatives
295+
"Security+*"
296+
```
297+
106298
### Date Filtering
107299

108300
Filter tasks by creation or modification date:
@@ -460,7 +652,7 @@ The tool dynamically fetches status information from your Phabricator/Phorge ins
460652

461653
**Open vs Closed**: Only Open and Blocked are "open" statuses. All others (Wontfix, Invalid, Duplicate, Resolved) are terminal/closed states.
462654

463-
**Status Progression**:
655+
**Status Progression**:
464656
- Moving from a lower number to a higher number is considered **"raised"** (forward progression)
465657
- Moving from a higher number to a lower number is considered **"lowered"** (regression/reopening)
466658
- For example: Open (0) → Resolved (5) is "raised" (task progressed forward)

phabfive/cli.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
from pprint import pprint as pp
88

99
# 3rd party imports
10-
from docopt import docopt, extras, Option, DocoptExit
11-
10+
from docopt import DocoptExit, Option, docopt, extras
1211

1312
base_args = """
1413
Usage:
@@ -117,10 +116,11 @@
117116
phabfive maniphest search <project_name> [options]
118117
119118
Search Arguments:
120-
<project_name> Project name or wildcard pattern.
121-
Supports: "*" (all projects), "prefix*" (starts with),
122-
"*suffix" (ends with), "*contains*" (contains text).
123-
Empty string "" returns no results.
119+
<project_name> Project name or filter pattern (supports OR/AND logic and wildcards).
120+
Supports: "*" (all projects), "prefix*" (starts with),
121+
"*suffix" (ends with), "*contains*" (contains text).
122+
Filter syntax: "ProjectA,ProjectB" (OR), "ProjectA+ProjectB" (AND).
123+
Empty string "" returns no results.
124124
125125
Search Options:
126126
--created-after=N Tasks created within the last N days
@@ -165,13 +165,13 @@
165165
raised - Status progressed forward
166166
lowered - Status moved backward
167167
not:PATTERN - Negates any pattern above
168-
Examples:
169-
been:Open
170-
from:Open:raised
171-
not:in:Resolved+raised
172-
in:Open,been:Resolved
173-
--show-history Display column, priority, and status transition history
174-
--show-metadata Display filter match metadata (which boards/priority/status matched)
168+
Examples:
169+
been:Open
170+
from:Open:raised
171+
not:in:Resolved+raised
172+
in:Open,been:Resolved
173+
--show-history Display column, priority, and status transition history
174+
--show-metadata Display filter match metadata (which boards/priority/status matched)
175175
176176
Options:
177177
--all Show all fields for a ticket
@@ -263,12 +263,11 @@ def run(cli_args, sub_args):
263263
Execute the CLI
264264
"""
265265
# Local imports required due to logging limitation
266-
from phabfive import passphrase, diffusion, paste, user, repl, maniphest
267-
from phabfive.maniphest_transitions import parse_transition_patterns
268-
from phabfive.priority_transitions import parse_priority_patterns
269-
from phabfive.status_transitions import parse_status_patterns
266+
from phabfive import diffusion, maniphest, passphrase, paste, repl, user
270267
from phabfive.constants import REPO_STATUS_CHOICES
271268
from phabfive.exceptions import PhabfiveException
269+
from phabfive.maniphest_transitions import parse_transition_patterns
270+
from phabfive.priority_transitions import parse_priority_patterns
272271

273272
retcode = 0
274273

@@ -401,7 +400,10 @@ def run(cli_args, sub_args):
401400
sub_args["--column"]
402401
)
403402
except Exception as e:
404-
print(f"ERROR: Invalid column filter pattern: {e}", file=sys.stderr)
403+
print(
404+
f"ERROR: Invalid column filter pattern: {e}",
405+
file=sys.stderr,
406+
)
405407
retcode = 1
406408
return retcode
407409

@@ -412,18 +414,25 @@ def run(cli_args, sub_args):
412414
sub_args["--priority"]
413415
)
414416
except Exception as e:
415-
print(f"ERROR: Invalid priority filter pattern: {e}", file=sys.stderr)
417+
print(
418+
f"ERROR: Invalid priority filter pattern: {e}",
419+
file=sys.stderr,
420+
)
416421
retcode = 1
417422
return retcode
418423

419424
status_patterns = None
420425
if sub_args.get("--status"):
421426
try:
422-
status_patterns = parse_status_patterns(
427+
# Parse status patterns with API-fetched status ordering
428+
status_patterns = maniphest_app.parse_status_patterns_with_api(
423429
sub_args["--status"]
424430
)
425431
except Exception as e:
426-
print(f"ERROR: Invalid status filter pattern: {e}", file=sys.stderr)
432+
print(
433+
f"ERROR: Invalid status filter pattern: {e}",
434+
file=sys.stderr,
435+
)
427436
retcode = 1
428437
return retcode
429438

0 commit comments

Comments
 (0)