Coverage for src/lexigram/auth/cli/generators/guard.py: 100%

26 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-26 00:58 +0800

1from __future__ import annotations 

2 

3from typing import Any 

4 

5from jinja2 import Environment, PackageLoader, select_autoescape 

6 

7from lexigram.codegen.base import GenerationResult, GeneratorBase 

8 

9 

10class AuthGuardGenerator(GeneratorBase): 

11 name = "guard" 

12 description = "Generate an authorization guard" 

13 default_output_dir = "src/guards" 

14 

15 def generate( 

16 self, 

17 name: str, 

18 **options: Any, 

19 ) -> GenerationResult: 

20 guard_type = options.get("type", "role") 

21 output_path = self.output_dir 

22 guard_name = self._to_pascal_case(name) 

23 guard_filename = f"{self._to_snake_case(name)}_guard.py" 

24 

25 context = { 

26 "guard_name": guard_name, 

27 "guard_name_snake": self._to_snake_case(name), 

28 "package_name": self._get_package_name(self.output_dir), 

29 "guard_type": guard_type, 

30 } 

31 

32 env = Environment( 

33 loader=PackageLoader("lexigram.auth.cli", "templates"), 

34 autoescape=select_autoescape(), 

35 ) 

36 template = env.get_template("guard.py.jinja2") 

37 content = template.render(**context) 

38 

39 file_path = output_path / guard_filename 

40 if file_path.exists() and not options.get("force", False): 

41 return GenerationResult() 

42 

43 if not options.get("dry_run", False): 

44 output_path.mkdir(parents=True, exist_ok=True) 

45 with open(file_path, "w") as f: 

46 f.write(content) 

47 return GenerationResult(files_created=[file_path]) 

48 

49 return GenerationResult()