Coverage for src\gibr\cli.py: 0%
70 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-20 08:09 +0300
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-20 08:09 +0300
1"""CLI for gibr."""
3import logging
4import os
6import click
7from git.config import GitConfigParser
8from tabulate import tabulate
10from gibr.branch import BranchName
11from gibr.config import GibrConfig
12from gibr.git import create_and_push_branch
13from gibr.logger import configure_logger
14from gibr.notify import party, success, warning
15from gibr.trackers.factory import get_tracker
18class GibrGroup(click.Group):
19 """Custom Click group."""
21 def parse_args(self, ctx, args):
22 """Parse args to handle 'git' alias routing and default command (create)."""
23 # If 'git' alias is present, handle it
24 if args and args[0] == "git":
25 args.pop(0)
27 # Move all flags (starting with '--') to the front
28 flags = [a for a in args if a.startswith("--")]
29 rest = [a for a in args if not a.startswith("--")]
30 args[:] = flags + rest
32 # Treat numeric as 'create' (gibr 123 -> gibr create 123)
33 for i, arg in enumerate(args):
34 if not arg.startswith("--"):
35 if arg.isdigit() and arg not in self.commands:
36 args.insert(i, "create")
37 break
39 return super().parse_args(ctx, args)
42@click.group(cls=GibrGroup)
43@click.option("--verbose", is_flag=True, help="Turn on verbose logging")
44@click.pass_context
45def cli(ctx, verbose):
46 """Gibr — streamline your git + issue tracker workflow."""
47 # Configure logging and echo verbose mode
48 configure_logger(verbose)
49 ctx.ensure_object(dict)
50 ctx.obj["verbose"] = verbose
51 logging.debug("Verbose modes enabled.")
53 # Initialize shared config and tracker once
54 config = GibrConfig().load()
55 ctx.obj["config"] = config
56 ctx.obj["tracker"] = get_tracker(config.config)
59@cli.command("create")
60@click.argument("issue_number")
61@click.pass_context
62def create(ctx, issue_number):
63 """Generate a branch based on the issue number provided."""
64 config = ctx.obj["config"]
65 tracker = ctx.obj["tracker"]
66 issue = tracker.get_issue(issue_number)
67 branch_name = BranchName(config.config["DEFAULT"]["branch_name_format"]).generate(
68 issue
69 )
70 click.echo(f"Generating branch name for issue #{issue.id}: {issue.title}")
71 click.echo(f"Branch name: {branch_name}")
72 create_and_push_branch(branch_name)
75@cli.command("issues")
76@click.pass_context
77def issues(ctx):
78 """List open issues from the tracker."""
79 tracker = ctx.obj["tracker"]
80 issues = tracker.list_issues()
81 if not issues:
82 warning("No open issues found.")
83 return
84 table = [[issue.id, issue.type, issue.title] for issue in issues]
86 click.echo(tabulate(table, headers=["Issue", "Type", "Title"], tablefmt="github"))
89@cli.command("alias")
90@click.pass_context
91def alias(ctx):
92 """Add git aliases for gibr commands."""
93 commands = [
94 name for name, cmd in ctx.parent.command.commands.items() if name != "alias"
95 ]
97 try:
98 config = GitConfigParser(os.path.expanduser("~/.gitconfig"), read_only=False)
99 for name in commands:
100 cmd = f"!gibr git {name}"
101 config.set_value("alias", name, cmd)
102 success(f"Added git alias: git {name} → {cmd}")
103 config.write()
104 party("Git aliases successfully added!")
105 except Exception as e:
106 raise click.ClickException(f"Failed to set git aliases: {e}")