phable-cli 0.1.15__tar.gz → 0.1.17__tar.gz
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.
- {phable_cli-0.1.15 → phable_cli-0.1.17}/PKG-INFO +6 -7
- {phable_cli-0.1.15 → phable_cli-0.1.17}/README.md +4 -3
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cache.py +4 -2
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/assign.py +7 -4
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/create.py +3 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/list.py +17 -2
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/main.py +2 -0
- phable_cli-0.1.17/phable/cli/set.py +58 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/status.py +5 -1
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/tag.py +5 -1
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/config.py +2 -1
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/display.py +27 -9
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/phabricator.py +4 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/task.py +10 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/pyproject.toml +2 -2
- {phable_cli-0.1.15 → phable_cli-0.1.17}/LICENSE +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/__init__.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/cache.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/comment.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/config.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/move.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/parent.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/report.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/show.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/subscribe.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/cli/utils.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/tests/conftest.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/tests/fixtures/simple_task.json +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/tests/phabricator_test.py +0 -0
- {phable_cli-0.1.15 → phable_cli-0.1.17}/phable/utils.py +0 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phable-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.17
|
|
4
4
|
Summary: Manage Phabricator tasks from the comfort of your terminal
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Author: Balthazar Rouberol
|
|
8
8
|
Author-email: br@imap.cc
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.11,<4.0
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -61,10 +59,11 @@ Commands:
|
|
|
61
59
|
move Move one or several task on their current project board
|
|
62
60
|
parent Manage task parents
|
|
63
61
|
report-done-tasks Print the details of all tasks in the `from` column and move them to the `to` column.
|
|
62
|
+
set Set the fields of one or multiple tasks
|
|
64
63
|
show Show task details
|
|
65
|
-
status Set the status of one or multiple tasks
|
|
64
|
+
status Set the status of one or multiple tasks [DEPRECATED]
|
|
66
65
|
subscribe Subscribe to one or multiple task ids
|
|
67
|
-
tag Add a tag on one or multiple tasks
|
|
66
|
+
tag Add a tag on one or multiple tasks [DEPRECATED]
|
|
68
67
|
```
|
|
69
68
|
|
|
70
69
|
## Setup
|
|
@@ -105,7 +104,7 @@ $ phable config aliases list
|
|
|
105
104
|
done = move --column 'Done' --milestone
|
|
106
105
|
review = move --column 'Needs Review' --milestone
|
|
107
106
|
wip = move --column 'In Progress' --milestone
|
|
108
|
-
team-report = list --owner
|
|
107
|
+
team-report = list --owner self --column 'In Progress' --column 'Needs Review' --column 'Blocked/Waiting' --column Done --milestone --format html
|
|
109
108
|
```
|
|
110
109
|
|
|
111
110
|
### Phabricator task IDs as clickable links in iTerm2
|
|
@@ -39,10 +39,11 @@ Commands:
|
|
|
39
39
|
move Move one or several task on their current project board
|
|
40
40
|
parent Manage task parents
|
|
41
41
|
report-done-tasks Print the details of all tasks in the `from` column and move them to the `to` column.
|
|
42
|
+
set Set the fields of one or multiple tasks
|
|
42
43
|
show Show task details
|
|
43
|
-
status Set the status of one or multiple tasks
|
|
44
|
+
status Set the status of one or multiple tasks [DEPRECATED]
|
|
44
45
|
subscribe Subscribe to one or multiple task ids
|
|
45
|
-
tag Add a tag on one or multiple tasks
|
|
46
|
+
tag Add a tag on one or multiple tasks [DEPRECATED]
|
|
46
47
|
```
|
|
47
48
|
|
|
48
49
|
## Setup
|
|
@@ -83,7 +84,7 @@ $ phable config aliases list
|
|
|
83
84
|
done = move --column 'Done' --milestone
|
|
84
85
|
review = move --column 'Needs Review' --milestone
|
|
85
86
|
wip = move --column 'In Progress' --milestone
|
|
86
|
-
team-report = list --owner
|
|
87
|
+
team-report = list --owner self --column 'In Progress' --column 'Needs Review' --column 'Blocked/Waiting' --column Done --milestone --format html
|
|
87
88
|
```
|
|
88
89
|
|
|
89
90
|
### Phabricator task IDs as clickable links in iTerm2
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
|
+
import getpass
|
|
4
5
|
import sys
|
|
5
6
|
import tempfile
|
|
6
7
|
import time
|
|
@@ -12,7 +13,7 @@ if not os.getenv("GITHUB_ACTIONS"):
|
|
|
12
13
|
CACHE_HOME_PER_PLATFORM = {
|
|
13
14
|
"darwin": Path.home() / "Library" / "Caches",
|
|
14
15
|
"linux": Path(os.getenv("XDG_CACHE_HOME", f"{Path.home()}/.config")),
|
|
15
|
-
"windows": Path("c:/", "Users",
|
|
16
|
+
"windows": Path("c:/", "Users", getpass.getuser(), "AppData", "Local", "Temp"),
|
|
16
17
|
}
|
|
17
18
|
else:
|
|
18
19
|
CACHE_HOME_PER_PLATFORM = {}
|
|
@@ -27,7 +28,8 @@ class Cache:
|
|
|
27
28
|
)
|
|
28
29
|
self.cache_dir = cache_parent_dir / "phind"
|
|
29
30
|
if not self.cache_dir.exists():
|
|
30
|
-
|
|
31
|
+
# create entire path if it doesn't exist
|
|
32
|
+
os.makedirs(self.cache_dir, exist_ok=True)
|
|
31
33
|
self.cache_filepath = self.cache_dir / "cache.json"
|
|
32
34
|
if self.cache_filepath.exists():
|
|
33
35
|
try:
|
|
@@ -38,13 +38,16 @@ def assign_task(
|
|
|
38
38
|
$ phable assign T123456
|
|
39
39
|
\b
|
|
40
40
|
# assign to username
|
|
41
|
-
$ phable assign T123456
|
|
41
|
+
$ phable assign T123456 --username brouberol
|
|
42
42
|
\b
|
|
43
|
-
# assign
|
|
44
|
-
$ phable assign T123456
|
|
43
|
+
# assign current user as a secondary owner
|
|
44
|
+
$ phable assign T123456 --username self --secondary
|
|
45
|
+
\b
|
|
46
|
+
# assign multiple tasks to current user
|
|
47
|
+
$ phable assign T123456 T234567 --usernamme self
|
|
45
48
|
|
|
46
49
|
"""
|
|
47
|
-
if not username:
|
|
50
|
+
if not username or (username == "self"):
|
|
48
51
|
user = client.current_user()
|
|
49
52
|
else:
|
|
50
53
|
user = client.find_user_by_username(username)
|
|
@@ -78,6 +78,9 @@ def create_task(
|
|
|
78
78
|
# Create a task with an associated owner
|
|
79
79
|
$ phable create --title 'A task' --owner brouberol
|
|
80
80
|
\b
|
|
81
|
+
# Create a task with an associated owner set to the current user
|
|
82
|
+
$ phable create --title 'A task' --owner self
|
|
83
|
+
\b
|
|
81
84
|
# Create a task with an associated subscriber
|
|
82
85
|
$ phable create --title 'A task' --cc brouberol
|
|
83
86
|
|
|
@@ -6,7 +6,7 @@ from phable.cli.utils import find_project_phid_by_title, project_phid_option
|
|
|
6
6
|
from phable.config import config
|
|
7
7
|
from phable.display import TaskFormat, display_tasks
|
|
8
8
|
from phable.phabricator import PhabricatorClient
|
|
9
|
-
|
|
9
|
+
from phable.task import TaskStatus
|
|
10
10
|
|
|
11
11
|
@click.command(name="list")
|
|
12
12
|
@click.option(
|
|
@@ -30,6 +30,13 @@ from phable.phabricator import PhabricatorClient
|
|
|
30
30
|
"milestone board, instead of the project board itself"
|
|
31
31
|
),
|
|
32
32
|
)
|
|
33
|
+
@click.option(
|
|
34
|
+
"--status",
|
|
35
|
+
required=False,
|
|
36
|
+
type=click.Choice(TaskStatus._member_names_), help="Task(s) status",
|
|
37
|
+
default=[TaskStatus.open, TaskStatus.progress, TaskStatus.stalled],
|
|
38
|
+
multiple=True,
|
|
39
|
+
)
|
|
33
40
|
@click.option(
|
|
34
41
|
"--format",
|
|
35
42
|
required=False,
|
|
@@ -46,6 +53,7 @@ def list_tasks(
|
|
|
46
53
|
project: Optional[str],
|
|
47
54
|
owner: Optional[str] = None,
|
|
48
55
|
milestone: bool = False,
|
|
56
|
+
status: list[str] = None,
|
|
49
57
|
format: TaskFormat = TaskFormat.PLAIN,
|
|
50
58
|
):
|
|
51
59
|
"""Lists and filter tasks
|
|
@@ -60,6 +68,9 @@ def list_tasks(
|
|
|
60
68
|
\b
|
|
61
69
|
# List all tasks owner by brouberol in the Done column of the default board latest milestone
|
|
62
70
|
$ phable list --milestone --owner brouberol --column Done
|
|
71
|
+
\b
|
|
72
|
+
# List all tasks owner by the current user in the Done column of the default board latest milestone
|
|
73
|
+
$ phable list --milestone --owner self --column Done
|
|
63
74
|
|
|
64
75
|
"""
|
|
65
76
|
if owner:
|
|
@@ -85,12 +96,16 @@ def list_tasks(
|
|
|
85
96
|
else:
|
|
86
97
|
column_phids = []
|
|
87
98
|
tasks = client.find_tasks(
|
|
88
|
-
column_phids=column_phids,
|
|
99
|
+
column_phids=column_phids,
|
|
100
|
+
owner_phid=owner_user,
|
|
101
|
+
project_phid=project_phid,
|
|
102
|
+
status=status,
|
|
89
103
|
)
|
|
90
104
|
tasks += client.find_tasks(
|
|
91
105
|
column_phids=column_phids,
|
|
92
106
|
backup_owner_phid=owner_user,
|
|
93
107
|
project_phid=project_phid,
|
|
108
|
+
status=status,
|
|
94
109
|
)
|
|
95
110
|
tasks = [client.enrich_task(task) for task in tasks]
|
|
96
111
|
display_tasks(tasks=tasks, format=format)
|
|
@@ -13,6 +13,7 @@ from phable.cli.list import list_tasks
|
|
|
13
13
|
from phable.cli.move import move_task
|
|
14
14
|
from phable.cli.parent import parent
|
|
15
15
|
from phable.cli.report import report_done_tasks
|
|
16
|
+
from phable.cli.set import set_task_fields
|
|
16
17
|
from phable.cli.show import show_task
|
|
17
18
|
from phable.cli.status import set_task_status
|
|
18
19
|
from phable.cli.subscribe import subscribe_to_task
|
|
@@ -102,6 +103,7 @@ cli.add_command(list_tasks)
|
|
|
102
103
|
cli.add_command(tag_task)
|
|
103
104
|
cli.add_command(parent)
|
|
104
105
|
cli.add_command(set_task_status)
|
|
106
|
+
cli.add_command(set_task_fields)
|
|
105
107
|
|
|
106
108
|
|
|
107
109
|
def runcli():
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
from phable.cli.utils import VARIADIC
|
|
6
|
+
from phable.phabricator import PhabricatorClient
|
|
7
|
+
from phable.task import TASK_ID, TaskPriority, TaskStatus
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@click.command(name="set")
|
|
11
|
+
@click.option(
|
|
12
|
+
"--priority",
|
|
13
|
+
type=click.Choice(TaskPriority._member_names_),
|
|
14
|
+
help="Task(s) priority",
|
|
15
|
+
)
|
|
16
|
+
@click.option(
|
|
17
|
+
"--status", type=click.Choice(TaskStatus._member_names_), help="Task(s) status"
|
|
18
|
+
)
|
|
19
|
+
@click.option("--tags", type=str, multiple=True, help="Task(s) tag(s)")
|
|
20
|
+
@click.argument("task-ids", type=TASK_ID, nargs=VARIADIC)
|
|
21
|
+
@click.pass_context
|
|
22
|
+
@click.pass_obj
|
|
23
|
+
def set_task_fields(
|
|
24
|
+
client: PhabricatorClient,
|
|
25
|
+
ctx: click.Context,
|
|
26
|
+
task_ids: list[int],
|
|
27
|
+
priority: Optional[str],
|
|
28
|
+
status: Optional[str],
|
|
29
|
+
tags: list[str],
|
|
30
|
+
):
|
|
31
|
+
"""Set the fields of one or multiple tasks
|
|
32
|
+
|
|
33
|
+
\b
|
|
34
|
+
Example:
|
|
35
|
+
# Set the priority for a single task
|
|
36
|
+
$ phable set T123456 --priority high
|
|
37
|
+
\b
|
|
38
|
+
# Set the priority for multiple tasks
|
|
39
|
+
$ phable set T123456 T123457 --priority medium
|
|
40
|
+
\b
|
|
41
|
+
# Set the status for a single task
|
|
42
|
+
$ phable set T123456 --status resolved
|
|
43
|
+
\b
|
|
44
|
+
# Set the tags for a single task
|
|
45
|
+
$ phable set T123456 --tags 'Epic' 'OKR'
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
tag_phids = []
|
|
49
|
+
for tag in tags:
|
|
50
|
+
if tag_meta := client.find_project_by_title(title=tag):
|
|
51
|
+
tag_phids.append(tag_meta["phid"])
|
|
52
|
+
else:
|
|
53
|
+
ctx.fail(f"Tag '{tag}' not found")
|
|
54
|
+
|
|
55
|
+
for task_id in task_ids:
|
|
56
|
+
params = {"priority": priority, "status": status}
|
|
57
|
+
params = {param: value for param, value in params.values() if value is not None}
|
|
58
|
+
client.create_or_edit_task(task_id=task_id, params=params)
|
|
@@ -16,7 +16,7 @@ from phable.task import TASK_ID, TaskStatus
|
|
|
16
16
|
def set_task_status(
|
|
17
17
|
client: PhabricatorClient, task_ids: list[int], status: Optional[str]
|
|
18
18
|
):
|
|
19
|
-
"""Set the status of one or multiple tasks
|
|
19
|
+
"""Set the status of one or multiple tasks [DEPRECATED]
|
|
20
20
|
|
|
21
21
|
\b
|
|
22
22
|
Example:
|
|
@@ -27,5 +27,9 @@ def set_task_status(
|
|
|
27
27
|
$ phable status T123456 T123457 --status declined
|
|
28
28
|
|
|
29
29
|
"""
|
|
30
|
+
click.secho(
|
|
31
|
+
"[DEPRECATION NOTICE] This command has been replaced by `phable set --status` and will soon be removed",
|
|
32
|
+
fg="yellow",
|
|
33
|
+
)
|
|
30
34
|
for task_id in task_ids:
|
|
31
35
|
client.set_task_status(task_id=task_id, status=status)
|
|
@@ -12,7 +12,7 @@ from phable.task import TASK_ID
|
|
|
12
12
|
@click.argument("task-ids", type=TASK_ID, nargs=VARIADIC)
|
|
13
13
|
@click.pass_obj
|
|
14
14
|
def tag_task(client: PhabricatorClient, task_ids: list[int], tag: Optional[str]):
|
|
15
|
-
"""Add a tag on one or multiple tasks
|
|
15
|
+
"""Add a tag on one or multiple tasks [DEPRECATED]
|
|
16
16
|
|
|
17
17
|
\b
|
|
18
18
|
Example:
|
|
@@ -20,6 +20,10 @@ def tag_task(client: PhabricatorClient, task_ids: list[int], tag: Optional[str])
|
|
|
20
20
|
$ phable tag T123456 T123457 --tag 'Essential work' # add multiple tags to a task
|
|
21
21
|
|
|
22
22
|
"""
|
|
23
|
+
click.secho(
|
|
24
|
+
"[DEPRECATION NOTICE] This command has been replaced by `phable set --tag` and will soon be removed",
|
|
25
|
+
fg="yellow",
|
|
26
|
+
)
|
|
23
27
|
if tag := client.find_project_by_title(title=tag):
|
|
24
28
|
for task_id in task_ids:
|
|
25
29
|
client.assign_tag_to_task(task_id=task_id, tag_phid=tag["phid"])
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import getpass
|
|
2
3
|
import sys
|
|
3
4
|
from configparser import ConfigParser
|
|
4
5
|
from dataclasses import dataclass, field
|
|
@@ -11,7 +12,7 @@ _warnings = []
|
|
|
11
12
|
CONFIG_HOME_PER_PLATFORM = {
|
|
12
13
|
"darwin": Path.home() / "Library" / "Preferences",
|
|
13
14
|
"linux": Path(os.getenv("XDG_CACHE_HOME", f"{Path.home()}/.config")),
|
|
14
|
-
"windows": Path("c:/", "Users",
|
|
15
|
+
"windows": Path("c:/", "Users", getpass.getuser(), "AppData", "Local", "Programs"),
|
|
15
16
|
}
|
|
16
17
|
config_filepath = CONFIG_HOME_PER_PLATFORM[sys.platform] / "phable" / "config.ini"
|
|
17
18
|
|
|
@@ -11,6 +11,8 @@ class TaskFormat(StrEnum):
|
|
|
11
11
|
HTML = auto()
|
|
12
12
|
MARKDOWN = auto()
|
|
13
13
|
WIKITEXT = auto()
|
|
14
|
+
ONELINE = auto()
|
|
15
|
+
IDS = auto()
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
def display_tasks(
|
|
@@ -34,7 +36,8 @@ class TaskPrinter:
|
|
|
34
36
|
pass
|
|
35
37
|
|
|
36
38
|
def print_list(self, tasks: list[dict]) -> None:
|
|
37
|
-
|
|
39
|
+
for task in tasks:
|
|
40
|
+
self.print(task)
|
|
38
41
|
|
|
39
42
|
def title(self, task: dict) -> str:
|
|
40
43
|
return f"{Task.from_int(task['id'])} {task['fields']['name']}"
|
|
@@ -55,19 +58,11 @@ class MarkdownTaskPrinter(TaskPrinter):
|
|
|
55
58
|
def print(self, task: dict) -> None:
|
|
56
59
|
self._printer(f"* [{self.title(task)}]({task['url']}) {self.status(task)}")
|
|
57
60
|
|
|
58
|
-
def print_list(self, tasks: list[dict]) -> None:
|
|
59
|
-
for task in tasks:
|
|
60
|
-
self.print(task)
|
|
61
|
-
|
|
62
61
|
|
|
63
62
|
class WikitextTaskPrinter(TaskPrinter):
|
|
64
63
|
def print(self, task: dict) -> None:
|
|
65
64
|
self._printer(f"* [{task['url']} {self.title(task)}] {self.status(task)}")
|
|
66
65
|
|
|
67
|
-
def print_list(self, tasks: list[dict]) -> None:
|
|
68
|
-
for task in tasks:
|
|
69
|
-
self.print(task)
|
|
70
|
-
|
|
71
66
|
|
|
72
67
|
class HtmlTaskPrinter(TaskPrinter):
|
|
73
68
|
def print(self, task: dict) -> None:
|
|
@@ -112,6 +107,25 @@ class PlainTaskPrinter(TaskPrinter):
|
|
|
112
107
|
self._printer("=" * 50)
|
|
113
108
|
|
|
114
109
|
|
|
110
|
+
class OneLineTaskPrinter(TaskPrinter):
|
|
111
|
+
def print(self, task: dict) -> None:
|
|
112
|
+
self._printer(
|
|
113
|
+
" ".join(
|
|
114
|
+
[
|
|
115
|
+
f"{Task.from_int(task['id'])}",
|
|
116
|
+
f"{task['fields']['status']['name']:<12}",
|
|
117
|
+
f"{task['fields']['priority']['name']:<12}",
|
|
118
|
+
task["fields"]["name"],
|
|
119
|
+
]
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class IdsTaskPrinter(TaskPrinter):
|
|
125
|
+
def print(self, task: dict) -> None:
|
|
126
|
+
self._printer(f"{Task.from_int(task['id'])}")
|
|
127
|
+
|
|
128
|
+
|
|
115
129
|
def get_printer(format: TaskFormat) -> TaskPrinter:
|
|
116
130
|
if format == TaskFormat.PLAIN:
|
|
117
131
|
return PlainTaskPrinter(print)
|
|
@@ -123,5 +137,9 @@ def get_printer(format: TaskFormat) -> TaskPrinter:
|
|
|
123
137
|
return MarkdownTaskPrinter(print)
|
|
124
138
|
elif format == TaskFormat.WIKITEXT:
|
|
125
139
|
return WikitextTaskPrinter(print)
|
|
140
|
+
elif format == TaskFormat.ONELINE:
|
|
141
|
+
return OneLineTaskPrinter(print)
|
|
142
|
+
elif format == TaskFormat.IDS:
|
|
143
|
+
return IdsTaskPrinter(print)
|
|
126
144
|
else:
|
|
127
145
|
raise ValueError(f"Unknown format: {format}")
|
|
@@ -173,6 +173,7 @@ class PhabricatorClient:
|
|
|
173
173
|
owner_phid: Optional[str] = None,
|
|
174
174
|
backup_owner_phid: Optional[str] = None,
|
|
175
175
|
project_phid: Optional[str] = None,
|
|
176
|
+
status: Optional[list[str]] = None,
|
|
176
177
|
) -> list[dict[str, Any]]:
|
|
177
178
|
params = {
|
|
178
179
|
"attachments[subscribers]": "true",
|
|
@@ -187,6 +188,9 @@ class PhabricatorClient:
|
|
|
187
188
|
params["constraints[custom.train.backup][0]"] = backup_owner_phid
|
|
188
189
|
if project_phid:
|
|
189
190
|
params["constraints[projects][0]"] = project_phid
|
|
191
|
+
if status:
|
|
192
|
+
for i, value in enumerate(status):
|
|
193
|
+
params[f"constraints[statuses][{i}]"] = value
|
|
190
194
|
return self._make_request("maniphest.search", params=params)["result"]["data"]
|
|
191
195
|
|
|
192
196
|
def find_subtasks(self, parent_id: int) -> list[dict[str, Any]]:
|
|
@@ -30,3 +30,13 @@ class TaskStatus(StrEnum):
|
|
|
30
30
|
stalled = "stalled"
|
|
31
31
|
invalid = "invalid"
|
|
32
32
|
declined = "declined"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# TODO these are hard-coded for Wikimedia's Phab, we should do something better
|
|
36
|
+
class TaskPriority(StrEnum):
|
|
37
|
+
lowest = "lowest"
|
|
38
|
+
low = "low"
|
|
39
|
+
medium = "medium"
|
|
40
|
+
high = "high"
|
|
41
|
+
unbreak = "unbreak"
|
|
42
|
+
triage = "triage"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "phable-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.17"
|
|
4
4
|
description = "Manage Phabricator tasks from the comfort of your terminal"
|
|
5
5
|
authors = ["Balthazar Rouberol <br@imap.cc>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -8,7 +8,7 @@ readme = "README.md"
|
|
|
8
8
|
packages = [{ include = "phable" }]
|
|
9
9
|
|
|
10
10
|
[tool.poetry.dependencies]
|
|
11
|
-
python = "^3.
|
|
11
|
+
python = "^3.11"
|
|
12
12
|
requests = "^2.32.3"
|
|
13
13
|
click = "^8.1.8"
|
|
14
14
|
pytest = "^8.3.5"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|