1+ import shutil
12import inspect
23from pathlib import Path
34from itertools import chain
5+ from typing import Union , cast
46from dataclasses import dataclass
5- from typing import Dict , List , Union , get_args , get_origin
7+ from typing_extensions import get_args , get_origin
68
9+ from githubkit import GitHubModel
710from jinja2 import Environment , PackageLoader
8- from githubkit .webhooks .models import GitHubWebhookModel
9- from githubkit .webhooks .types import webhook_action_types
11+ from githubkit .versions .latest .webhooks import webhook_action_types
1012
1113MESSAGE_EVENTS = {
1214 "CommitCommentCreated" ,
2628
2729@dataclass
2830class Data :
31+ action : str | None
2932 class_name : str
30- payload_type : str
33+ payload_types : list [ str ]
3134
3235
3336def pascal_case (* names : str ) -> str :
@@ -36,43 +39,72 @@ def pascal_case(*names: str) -> str:
3639
3740
3841def build_event ():
39- imports : List [str ] = []
40- events : List [Data ] = []
41- event_types : Dict [str , Union [str , Dict [str , str ]]] = {}
42+ event_types : dict [str , list [Data ]] = {}
4243 for event , types in webhook_action_types .items ():
44+ # event has no sub action
4345 if not isinstance (types , dict ):
44- imports .append (f"{ types .__name__ } as { types .__name__ } Payload" )
45- events .append (Data (types .__name__ , f"{ types .__name__ } Payload" ))
46- event_types [event ] = types .__name__
46+ types = cast (type [GitHubModel ], types )
47+ event_types [event ] = [
48+ Data (
49+ None ,
50+ types .__name__ .removeprefix ("Webhook" ),
51+ [types .__name__ ],
52+ )
53+ ]
4754 continue
4855
49- action_types : Dict [ str , str ] = {}
56+ action_types : list [ Data ] = []
5057 event_types [event ] = action_types
51- for action , type in types .items ():
52- if inspect .isclass (type ) and issubclass (type , GitHubWebhookModel ):
53- imports .append (f"{ type .__name__ } as { type .__name__ } Payload" )
54- events .append (Data (type .__name__ , f"{ type .__name__ } Payload" ))
55- action_types [action ] = type .__name__
58+ for action , model in types .items ():
59+ # action type is a simple model
60+ if inspect .isclass (model ) and issubclass (model , GitHubModel ):
61+ action_types .append (
62+ Data (
63+ action , model .__name__ .removeprefix ("Webhook" ), [model .__name__ ]
64+ )
65+ )
66+ # action type is a union of models
5667 else :
57- assert get_origin (type ) is Union
58- imports .extend (model .__name__ for model in get_args (type ))
59- events .append (
68+ assert get_origin (model ) is Union
69+ action_types .append (
6070 Data (
71+ action ,
6172 pascal_case (event , action ),
62- "Union["
63- f"{ ', ' .join (model .__name__ for model in get_args (type ))} "
64- "]" ,
73+ [model .__name__ for model in get_args (model )],
6574 )
6675 )
67- action_types [action ] = pascal_case (event , action )
76+
77+ output_dir = Path ("./nonebot/adapters/github/event/" )
78+
79+ if output_dir .exists ():
80+ shutil .rmtree (output_dir )
81+
82+ output_dir .mkdir (parents = True , exist_ok = True )
6883
6984 env = Environment (loader = PackageLoader ("codegen" ))
85+
86+ # generate base model
87+ template = env .get_template ("_base.py.jinja" )
88+ base_text = template .render ()
89+ (output_dir / "_base.py" ).write_text (base_text )
90+
91+ # generate types
92+ template = env .get_template ("_types.py.jinja" )
93+ types_text = template .render (types = event_types )
94+ (output_dir / "_types.py" ).write_text (types_text )
95+
96+ # generate event models
7097 template = env .get_template ("event.py.jinja" )
71- event_text = template .render (
72- imports = imports ,
73- events = events ,
74- types = event_types ,
75- message_events = MESSAGE_EVENTS ,
76- has_message_events = HAS_MESSAGE_EVENTS ,
77- )
78- Path ("./nonebot/adapters/github/event.py" ).write_text (event_text )
98+ for event , actions in event_types .items ():
99+ event_text = template .render (
100+ event = event ,
101+ actions = actions ,
102+ message_events = MESSAGE_EVENTS ,
103+ has_message_events = HAS_MESSAGE_EVENTS ,
104+ )
105+ (output_dir / f"{ event } .py" ).write_text (event_text )
106+
107+ # generate init file
108+ template = env .get_template ("__init__.py.jinja" )
109+ init_text = template .render (types = event_types )
110+ (output_dir / "__init__.py" ).write_text (init_text )
0 commit comments