Added a DocC catalog coverage check.
This commit is contained in:
1 parent
2cfacd0e14
commit
ff00fdd852
9 files changed
+134
-42
No files matched your search
@@ -0,0 +1,83 @@
|
||||
# ===------------------------------------------------------------------------------------===
|
||||
#
|
||||
# This source file is part of the App Store Connect Service open source project
|
||||
#
|
||||
# Copyright (c) 2026 Röck+Cöde VoF. and the App Store Connect Service project authors
|
||||
# Licensed under Apache license v2.0
|
||||
#
|
||||
# See LICENSE for license information
|
||||
# See CONTRIBUTORS for the list of App Store Connect Service project authors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# ===------------------------------------------------------------------------------------===
|
||||
|
||||
"""Checks that the DocC catalog lists every generated operation and schema, and nothing else.
|
||||
|
||||
Usage: python3 check-docc.py <generated sources folder> <DocC catalog folder>
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def generated_symbols(types_path):
|
||||
"""Returns the methods, operations, and schemas in the generated `Types.swift` file."""
|
||||
lines = open(types_path).read().split('\n')
|
||||
|
||||
def start(prefix):
|
||||
return next(index for index, line in enumerate(lines) if line.startswith(prefix))
|
||||
|
||||
protocol = lines[start('public protocol APIProtocol'):start('extension APIProtocol {')]
|
||||
components = lines[start('public enum Components {'):start('public enum Operations {')]
|
||||
operations = lines[start('public enum Operations {'):]
|
||||
|
||||
schema = re.compile(r' (?:@\w+ )*public (?:indirect )?(?:struct|enum|typealias) (\w+)')
|
||||
|
||||
return {
|
||||
'APIProtocol.md': {m.group(1) for line in protocol if (m := re.match(r' func (\w+)\(', line))},
|
||||
'Operations.md': {m.group(1) for line in operations if (m := re.match(r' public enum (\w+)', line))},
|
||||
'Components.md': {m.group(1) for line in components if (m := schema.match(line))},
|
||||
}
|
||||
|
||||
|
||||
def documented_symbols(catalog_path):
|
||||
"""Returns the symbols listed in the DocC catalog topics."""
|
||||
patterns = {
|
||||
'APIProtocol.md': r'``(\w+)\(_:\)``',
|
||||
'Operations.md': r'``Operations/(\w+)``',
|
||||
'Components.md': r'``Components/Schemas/(\w+)``',
|
||||
}
|
||||
|
||||
return {
|
||||
name: set(re.findall(pattern, open(f'{catalog_path}/Extensions/{name}').read()))
|
||||
for name, pattern in patterns.items()
|
||||
}
|
||||
|
||||
|
||||
def main(generated_path, catalog_path):
|
||||
generated = generated_symbols(f'{generated_path}/Types.swift')
|
||||
documented = documented_symbols(catalog_path)
|
||||
is_up_to_date = True
|
||||
|
||||
for name in generated:
|
||||
missing = sorted(generated[name] - documented[name])
|
||||
stale = sorted(documented[name] - generated[name])
|
||||
|
||||
for title, symbols in [('Missing from', missing), ('Stale in', stale)]:
|
||||
if symbols:
|
||||
is_up_to_date = False
|
||||
print(f'{title} {name} ({len(symbols)}):')
|
||||
print('\n'.join(f' - {symbol}' for symbol in symbols))
|
||||
|
||||
if is_up_to_date:
|
||||
print('The DocC catalog lists every generated operation and schema.')
|
||||
|
||||
return 0 if is_up_to_date else 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
sys.exit(__doc__)
|
||||
|
||||
sys.exit(main(sys.argv[1], sys.argv[2]))
|
||||
Reference in new issue
Block a user