feat: CLI add search/transition/stats commands
This commit is contained in:
53
cli.py
53
cli.py
@@ -110,6 +110,41 @@ def cmd_health(args):
|
|||||||
print(f"Status: {result['status']}")
|
print(f"Status: {result['status']}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_search(args):
|
||||||
|
params = [f"q={args.query}"]
|
||||||
|
if args.project:
|
||||||
|
params.append(f"project_id={args.project}")
|
||||||
|
qs = "&".join(params)
|
||||||
|
issues = _request("GET", f"/search/issues?{qs}")
|
||||||
|
if not issues:
|
||||||
|
print(" No results found.")
|
||||||
|
return
|
||||||
|
for i in issues:
|
||||||
|
status_icon = {"open": "\U0001f7e2", "in_progress": "\U0001f535", "resolved": "\u2705", "closed": "\u26ab", "blocked": "\U0001f534"}.get(i["status"], "\u2753")
|
||||||
|
type_icon = {"resolution": "\u2696\ufe0f", "task": "\U0001f4cb", "story": "\U0001f4d6", "test": "\U0001f9ea"}.get(i["issue_type"], "\U0001f4cc")
|
||||||
|
print(f" {status_icon} {type_icon} #{i['id']} [{i['priority']}] {i['title']}")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_transition(args):
|
||||||
|
result = _request("POST", f"/issues/{args.issue_id}/transition?new_status={args.status}")
|
||||||
|
print(f"Issue #{result['id']} transitioned to: {result['status']}")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_stats(args):
|
||||||
|
params = f"?project_id={args.project}" if args.project else ""
|
||||||
|
stats = _request("GET", f"/dashboard/stats{params}")
|
||||||
|
print(f"Total: {stats['total']}")
|
||||||
|
print("By status:")
|
||||||
|
for s, c in stats["by_status"].items():
|
||||||
|
if c > 0:
|
||||||
|
print(f" {s}: {c}")
|
||||||
|
print("By type:")
|
||||||
|
for t, c in stats["by_type"].items():
|
||||||
|
if c > 0:
|
||||||
|
print(f" {t}: {c}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="HarborForge CLI")
|
parser = argparse.ArgumentParser(description="HarborForge CLI")
|
||||||
sub = parser.add_subparsers(dest="command")
|
sub = parser.add_subparsers(dest="command")
|
||||||
@@ -151,6 +186,21 @@ def main():
|
|||||||
# health
|
# health
|
||||||
sub.add_parser("health", help="Health check")
|
sub.add_parser("health", help="Health check")
|
||||||
|
|
||||||
|
|
||||||
|
# search
|
||||||
|
p_search = sub.add_parser("search", help="Search issues")
|
||||||
|
p_search.add_argument("query")
|
||||||
|
p_search.add_argument("--project", "-p", type=int)
|
||||||
|
|
||||||
|
# transition
|
||||||
|
p_trans = sub.add_parser("transition", help="Transition issue status")
|
||||||
|
p_trans.add_argument("issue_id", type=int)
|
||||||
|
p_trans.add_argument("status", choices=["open", "in_progress", "resolved", "closed", "blocked"])
|
||||||
|
|
||||||
|
# stats
|
||||||
|
p_stats = sub.add_parser("stats", help="Dashboard stats")
|
||||||
|
p_stats.add_argument("--project", "-p", type=int)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if not args.command:
|
if not args.command:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
@@ -164,6 +214,9 @@ def main():
|
|||||||
"users": cmd_users,
|
"users": cmd_users,
|
||||||
"version": cmd_version,
|
"version": cmd_version,
|
||||||
"health": cmd_health,
|
"health": cmd_health,
|
||||||
|
"search": cmd_search,
|
||||||
|
"transition": cmd_transition,
|
||||||
|
"stats": cmd_stats,
|
||||||
}
|
}
|
||||||
cmds[args.command](args)
|
cmds[args.command](args)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user