1212from aio .core import directory as _directory , event , subprocess
1313from aio .run import checker
1414
15+ from envoy .base .utils import IProject
1516from envoy .code .check import abstract , typing
1617
1718
@@ -51,13 +52,16 @@ class ACodeChecker(
5152 """Code checker."""
5253
5354 checks = (
55+ "changelogs_changes" ,
56+ "changelogs_pending" ,
5457 "extensions_fuzzed" ,
5558 "extensions_metadata" ,
5659 "extensions_registered" ,
5760 "glint" ,
5861 "python_yapf" ,
5962 "python_flake8" ,
60- "shellcheck" )
63+ "shellcheck" ,
64+ "version" )
6165
6266 @property
6367 def all_files (self ) -> bool :
@@ -177,6 +181,15 @@ def grep_matching_re(self) -> Optional[Pattern[str]]:
177181 def path (self ) -> pathlib .Path :
178182 return super ().path
179183
184+ @cached_property
185+ def project (self ) -> IProject :
186+ return self .project_class (self .path )
187+
188+ @property # type:ignore
189+ @abstracts .interfacemethod
190+ def project_class (self ) -> Type [IProject ]:
191+ raise NotImplementedError
192+
180193 @cached_property
181194 def shellcheck (self ) -> "abstract.AShellcheckCheck" :
182195 """Shellcheck checker."""
@@ -192,6 +205,17 @@ def summary_class(self) -> Type[CodeCheckerSummary]:
192205 """CodeChecker's summary class."""
193206 return CodeCheckerSummary
194207
208+ @cached_property
209+ def version_history (self ) -> "abstract.AVersionHistoryCheck" :
210+ """VERSION_HISTORY checker."""
211+ return self .version_history_class (
212+ self .project , self .directory , fix = self .fix )
213+
214+ @property # type:ignore
215+ @abstracts .interfacemethod
216+ def version_history_class (self ) -> Type ["abstract.AVersionHistoryCheck" ]:
217+ raise NotImplementedError
218+
195219 @cached_property
196220 def yapf (self ) -> "abstract.AYapfCheck" :
197221 """YAPF checker."""
@@ -210,6 +234,45 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
210234 parser .add_argument ("-s" , "--since" )
211235 parser .add_argument ("--extensions_build_config" )
212236
237+ async def check_changelogs_changes (self ):
238+ for changelog in self .project .changelogs .values ():
239+ errors = self .version_history .version_file (
240+ self .project , changelog ).run_checks ()
241+ if errors :
242+ self .error ("changelogs_changes" , errors )
243+ else :
244+ self .succeed (
245+ "changelogs_changes" ,
246+ [f"{ changelog .version } " ])
247+
248+ async def check_changelogs_pending (self ):
249+ pending = [
250+ k .base_version
251+ for k , v in self .project .changelogs .items ()
252+ if v .release_date == "Pending" ]
253+ all_good = (
254+ not pending
255+ or (self .project .is_dev
256+ and (pending
257+ == [self .project .version .base_version ])))
258+ if all_good :
259+ self .succeed (
260+ "changelog_pending" ,
261+ ["No extraneous pending versions found" ])
262+ return
263+ pending = [
264+ x for x
265+ in pending
266+ if x != self .project .version .base_version ]
267+ if self .project .is_dev :
268+ self .error (
269+ "changelog_pending" ,
270+ [f"Only current version should be pending, found: { pending } " ])
271+ else :
272+ self .error (
273+ "changelog_pending" ,
274+ [f"Nothing should be pending, found: { pending } " ])
275+
213276 async def check_extensions_fuzzed (self ) -> None :
214277 """Check for glint issues."""
215278 if self .extensions .all_fuzzed :
@@ -258,6 +321,44 @@ async def check_shellcheck(self) -> None:
258321 """Check for shellcheck issues."""
259322 await self ._code_check (self .shellcheck )
260323
324+ async def check_version (self ) -> None :
325+ is_current = self .project .is_current (
326+ self .project .changelogs .current )
327+ if is_current :
328+ self .succeed (
329+ "version" ,
330+ ["VERSION.txt version matches most recent changelog" ])
331+ else :
332+ self .error (
333+ "version" ,
334+ ["VERSION.txt does not match most recent changelog" ])
335+ not_pending = (
336+ self .project .is_dev
337+ and not self .project .changelogs .is_pending )
338+ not_dev = (
339+ not self .project .is_dev
340+ and self .project .changelogs .is_pending )
341+ if not_pending :
342+ self .error (
343+ "version" ,
344+ ["VERSION.txt is set to `-dev` but most recent changelog "
345+ "is not `Pending`" ])
346+ elif not_dev :
347+ self .error (
348+ "version" ,
349+ ["VERSION.txt is not set to `-dev` but most recent changelog "
350+ "is `Pending`" ])
351+ elif self .project .is_dev :
352+ self .succeed (
353+ "version" ,
354+ ["VERSION.txt is set to `-dev` and most recent changelog "
355+ "is `Pending`" ])
356+ else :
357+ self .succeed (
358+ "version" ,
359+ ["VERSION.txt is not set to `-dev` and most recent "
360+ "changelog is not `Pending`" ])
361+
261362 @checker .preload (
262363 when = ["python_flake8" ],
263364 catches = [subprocess .exceptions .OSCommandError ])
0 commit comments