Coverage for src / mysingle / cli / protos / commands / status.py: 0%
54 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-02 00:58 +0900
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-02 00:58 +0900
1"""
2Status 명령 - 서비스별 proto 파일 상태 확인.
3"""
5from __future__ import annotations
7import argparse
9from ..models import ProtoConfig, ServiceProtoInfo
10from ..utils import Color, LogLevel, colorize, log, log_header, log_table
13def discover_services(config: ProtoConfig) -> list[ServiceProtoInfo]:
14 """서비스 디렉터리에서 proto 정보 스캔"""
15 if not config.services_root.exists():
16 # 서비스 submodule에서 실행한 경우 빈 리스트 반환
17 return []
19 log_header("서비스 스캔")
20 result: list[ServiceProtoInfo] = []
21 skipped = 0
23 for service_dir in sorted(p for p in config.services_root.iterdir() if p.is_dir()):
24 proto_dir = service_dir / "protos"
25 if not proto_dir.exists():
26 log(
27 f"건너뛰기: {colorize(service_dir.name, Color.DIM)} (protos 디렉터리 없음)",
28 LogLevel.WARNING,
29 )
30 skipped += 1
31 continue
32 files = sorted(proto_dir.rglob("*.proto"))
33 if not files:
34 log(
35 f"건너뛰기: {colorize(service_dir.name, Color.DIM)} (proto 파일 없음)",
36 LogLevel.WARNING,
37 )
38 skipped += 1
39 continue
40 result.append(ServiceProtoInfo(service_dir.name, service_dir, proto_dir, files))
41 log(
42 f"발견: {colorize(service_dir.name, Color.GREEN)} ({len(files)}개 파일)",
43 LogLevel.SUCCESS,
44 )
46 log(
47 f"\n총 {colorize(str(len(result)), Color.BRIGHT_GREEN, bold=True)}개 서비스 발견 (건너뜀: {skipped}개)",
48 LogLevel.INFO,
49 )
50 return result
53def execute(args: argparse.Namespace, config: ProtoConfig) -> int:
54 """Status 명령 실행"""
55 # Submodule 내에서 실행 시 경고
56 if not config.services_root.exists():
57 log(
58 "⚠️ 이 명령은 grpc-protos 메인 저장소에서만 사용할 수 있습니다.",
59 LogLevel.WARNING,
60 )
61 log(
62 "서비스 디렉터리의 submodule에서는 'proto-cli version' 또는 'proto-cli validate'를 사용하세요.",
63 LogLevel.INFO,
64 )
65 return 1
67 services = discover_services(config)
69 if not services:
70 log("발견된 서비스가 없습니다.", LogLevel.WARNING)
71 return 1
73 log_header("서비스별 Proto 파일 현황")
75 rows = []
76 for service in services:
77 rows.append([service.name, str(len(service.files)), str(service.proto_dir)])
79 log_table(["서비스 이름", "Proto 파일 수", "경로"], rows)
81 # 상세 모드
82 if args.verbose:
83 log_header("Proto 파일 상세 목록")
84 for service in services:
85 print(f"\n{colorize(service.name, Color.BRIGHT_CYAN, bold=True)}:")
86 for proto_file in service.files:
87 rel_path = proto_file.relative_to(service.proto_dir)
88 print(f" • {rel_path}")
90 return 0
93def execute_interactive(config: ProtoConfig) -> int:
94 """대화형 모드로 status 명령 실행"""
95 from ...utils import ask_confirm
97 # 상세 모드 선택
98 verbose = ask_confirm("Proto 파일 상세 목록을 표시하시겠습니까?", default=False)
100 args = argparse.Namespace(verbose=verbose)
101 return execute(args, config)
104def setup_parser(parser: argparse.ArgumentParser) -> None:
105 """Status 명령 파서 설정"""
106 parser.add_argument(
107 "-v",
108 "--verbose",
109 action="store_true",
110 help="Proto 파일 상세 목록 출력",
111 )