Coverage for src / repo_sync_kitty / cli.py: 77%

35 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-23 09:31 -0500

1"""Main CLI application using Typer.""" 

2 

3import os 

4from pathlib import Path 

5from typing import Annotated 

6 

7import typer 

8from rich.console import Console 

9 

10from repo_sync_kitty import __version__ 

11from repo_sync_kitty.commands import add, check, init, scan, status, sync 

12 

13# Initialize Sentry if DSN is provided 

14if dsn := os.getenv("SENTRY_DSN"): 14 ↛ 15line 14 didn't jump to line 15 because the condition on line 14 was never true

15 try: 

16 import sentry_sdk 

17 

18 sentry_sdk.init(dsn=dsn, release=f"repo-sync-kitty@{__version__}") 

19 except ImportError: 

20 pass # sentry-sdk not installed, skip 

21 

22console = Console() 

23 

24app = typer.Typer( 

25 name="repo-sync-kitty", 

26 help="Git repository synchronization tool for teams.", 

27 add_completion=False, 

28 no_args_is_help=True, 

29) 

30 

31 

32def version_callback(value: bool) -> None: 

33 """Print version and exit.""" 

34 if value: 

35 console.print(f"repo-sync-kitty {__version__}") 

36 raise typer.Exit() 

37 

38 

39@app.callback() 

40def main( 

41 ctx: typer.Context, 

42 version: Annotated[ # noqa: ARG001 

43 bool, 

44 typer.Option( 

45 "--version", 

46 "-V", 

47 callback=version_callback, 

48 is_eager=True, 

49 help="Show version and exit.", 

50 ), 

51 ] = False, 

52 manifest: Annotated[ 

53 Path | None, 

54 typer.Option( 

55 "--manifest", 

56 "-m", 

57 help="Path to manifest.toml file.", 

58 envvar="REPO_SYNC_KITTY_MANIFEST", 

59 ), 

60 ] = None, 

61 root: Annotated[ 

62 Path | None, 

63 typer.Option( 

64 "--root", 

65 "-r", 

66 help="Root directory for repositories.", 

67 envvar="REPO_SYNC_KITTY_ROOT", 

68 ), 

69 ] = None, 

70 no_color: Annotated[ 

71 bool, 

72 typer.Option("--no-color", help="Disable colored output."), 

73 ] = False, 

74 verbose: Annotated[ 

75 bool, 

76 typer.Option("--verbose", "-v", help="Enable verbose output."), 

77 ] = False, 

78) -> None: 

79 """Git repository synchronization tool for teams.""" 

80 # Store global options in context for subcommands to access 

81 ctx.ensure_object(dict) 

82 ctx.obj["manifest"] = manifest 

83 ctx.obj["root"] = root 

84 ctx.obj["verbose"] = verbose 

85 if no_color: 85 ↛ 86line 85 didn't jump to line 86 because the condition on line 85 was never true

86 console.no_color = True 

87 

88 

89# Register commands 

90app.command(name="sync")(sync.sync) 

91app.command(name="status")(status.status) 

92app.command(name="init")(init.init) 

93app.command(name="add")(add.add) 

94app.command(name="check")(check.check) 

95app.command(name="scan")(scan.scan) 

96 

97 

98if __name__ == "__main__": 98 ↛ 99line 98 didn't jump to line 99 because the condition on line 98 was never true

99 app()