77from sphobjinv import Inventory
88
99DOCS_BASE_URL = "https://codingame.readthedocs.io/en/"
10+ STDLIB_DOCS_BASE_URL = "https://docs.python.org/"
1011
1112ref_to_doc_branch = {"dev" : "latest" , "master" : "stable" }
1213roles = {
@@ -40,6 +41,7 @@ def main():
4041 docs_changelog = repo .get_contents (
4142 "docs/changelog.rst" , settings .github_ref .split ("/" )[- 1 ]
4243 )
44+ log ("debug" , f"docs/changelog.rst at { settings .github_ref_name } downloaded" )
4345
4446 docs_url = (
4547 DOCS_BASE_URL
@@ -50,43 +52,100 @@ def main():
5052 )
5153 + "/"
5254 )
55+ log ("notice" , f"Using docs at { docs_url } " )
5356
5457 inventory = Inventory (url = docs_url + "objects.inv" )
58+ log ("debug" , "Downloaded codingame's inventory" )
59+ stdlib_inventory = Inventory (url = STDLIB_DOCS_BASE_URL + "objects.inv" )
60+ log ("debug" , "Downloaded stdlib's inventory" )
5561
5662 content = docs_changelog .decoded_content .decode ()
5763 new_content = content
5864 directives : typing .List [re .Match ] = list (
5965 re .finditer (r":(\w+):`(.+?)`" , content )
6066 )
67+ log ("debug" , f"Found { len (directives )} in docs/changelog.rst" )
68+
6169 links : typing .List [str ] = []
70+ cache : typing .Dict [str , int ] = {}
71+ stdlib_cache : typing .Dict [str , int ] = {}
72+
73+ log ("group" , "Directive search" )
6274
6375 for directive in directives :
64- if directive [1 ] == "ref" :
65- links .append ("`{} <{}>`__" .format (* refs [directive [2 ]]))
66- else :
67- role = roles .get (directive [1 ], directive [1 ])
68- try :
69- index = [
76+ role , name = directive .groups ()
77+ if role == "ref" :
78+ links .append ("`{} <{}>`__" .format (* refs [name ]))
79+ log ("debug" , f"Found :ref:`{ name } `" )
80+ continue
81+
82+ role = roles .get (role , role )
83+
84+ index = None
85+ stdlib = False
86+ cached = False
87+
88+ if f"{ role } :{ name } " in cache :
89+ index = cache [f"{ role } :{ name } " ]
90+ cached = True
91+
92+ if f"{ role } :{ name } " in stdlib_cache :
93+ index = stdlib_cache [f"{ role } :{ name } " ]
94+ stdlib = True
95+ cached = True
96+
97+ if index is None :
98+ indexes = [
99+ i
100+ for _ , i in inventory .suggest (
101+ f":py:{ role } :`codingame.{ name } `" ,
102+ with_index = True ,
103+ thresh = 90 ,
104+ )
105+ ]
106+
107+ if not indexes :
108+ indexes = [
70109 i
71- for _ , i in inventory .suggest (
72- f":py:{ role } :`codingame. { directive [ 2 ] } `" ,
110+ for _ , i in stdlib_inventory .suggest (
111+ f":py:{ role } :`{ name } `" ,
73112 with_index = True ,
74113 thresh = 90 ,
75114 )
76- ][0 ]
77- except IndexError :
78- print (
79- "::warning file=CHANGELOG.rst:: "
80- f":py:{ role } :`codingame.{ directive [2 ]} ` not found"
115+ ]
116+ stdlib = True
117+
118+ if not indexes :
119+ links .append (f"``{ name } ``" )
120+ log (
121+ "warning" ,
122+ f":py:{ role } :`codingame.{ name } ` or "
123+ f":py:{ role } :`{ name } ` not found" ,
124+ title = "Directive not found" ,
81125 )
82- links .append (f"``{ directive [2 ]} ``" )
83126 continue
84127
85- obj = inventory .objects [index ]
128+ index = indexes [0 ]
129+
130+ if stdlib :
131+ obj = stdlib_inventory .objects [index ]
86132 links .append (
87- f"`{ obj .dispname_expanded [ len ( 'codingame.' ):] } "
88- f"<{ docs_url + obj .uri_expanded } >`__"
133+ f"`{ obj .dispname_expanded } "
134+ f"<{ STDLIB_DOCS_BASE_URL + obj .uri_expanded } >`__"
89135 )
136+ log ("debug" , f"Found :{ role } :`{ name } `" + " (cached)" * cached )
137+ stdlib_cache [f"{ role } :{ name } " ] = index
138+ continue
139+
140+ obj = inventory .objects [index ]
141+ links .append (
142+ f"`{ obj .dispname_expanded [len ('codingame.' ):]} "
143+ f"<{ docs_url + obj .uri_expanded } >`__"
144+ )
145+ log ("debug" , f"Found :{ role } :`codingame.{ name } `" + " (cached)" * cached )
146+ cache [f"{ role } :{ name } " ] = index
147+
148+ log ("endgroup" )
90149
91150 for directive , link in zip (directives [::- 1 ], links [::- 1 ]):
92151 new_content = (
@@ -102,6 +161,8 @@ def main():
102161 changelog = repo .get_contents (
103162 "CHANGELOG.rst" , settings .github_ref .split ("/" )[- 1 ]
104163 )
164+ log ("debug" , f"CHANGELOG.rst at { settings .github_ref_name } downloaded" )
165+
105166 if new_content != changelog .decoded_content .decode ():
106167 repo .update_file (
107168 changelog .path ,
@@ -110,15 +171,74 @@ def main():
110171 changelog .sha ,
111172 branch = settings .github_ref .split ("/" )[- 1 ],
112173 )
174+ log (
175+ "notice" ,
176+ "Changelog's content changed, updated CHANGELOG.rst" ,
177+ file = "CHANGELOG.rst" ,
178+ )
179+ else :
180+ log ("notice" , "Changelog's content hasn't changed" )
181+
182+
183+ LOG_PARAMETER_NAMES = {
184+ "end_line" : "endLine" ,
185+ "column" : "col" ,
186+ "end_column" : "endColumn" ,
187+ }
188+
189+
190+ def log (
191+ level : str ,
192+ message : str = "" ,
193+ title : str = None ,
194+ file : str = None ,
195+ line : int = None ,
196+ end_line : int = None ,
197+ column : int = None ,
198+ end_column : int = None ,
199+ ):
200+ parameters = dict (
201+ filter (
202+ lambda i : i [1 ] is not None ,
203+ {
204+ "title" : title ,
205+ "file" : file ,
206+ "line" : line ,
207+ "end_line" : end_line ,
208+ "column" : column ,
209+ "end_column" : end_column ,
210+ }.items (),
211+ )
212+ )
213+
214+ print (
215+ "::"
216+ + level
217+ + (
218+ (
219+ " "
220+ + "," .join (
221+ f"{ LOG_PARAMETER_NAMES .get (k , k )} ={ v } "
222+ for k , v in parameters .items ()
223+ )
224+ )
225+ if parameters
226+ else ""
227+ )
228+ + "::"
229+ + message ,
230+ flush = True ,
231+ )
113232
114233
115234if __name__ == "__main__" :
116235 try :
117236 main ()
118237 except Exception as e :
119- print (
120- "::error file=.github/actions/changelog/main.py,"
121- f"title={ e .__class__ .__name__ } : { str (e )} :: "
122- + traceback .format_exc ()
238+ log (
239+ "error" ,
240+ traceback .format_exc (),
241+ title = f"{ e .__class__ .__name__ } : { str (e )} " ,
242+ file = ".github/actions/changelog/main.py" ,
123243 )
124244 raise
0 commit comments