|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +Copyright 2023 The Magma Authors. |
| 4 | +
|
| 5 | +This source code is licensed under the BSD-style license found in the |
| 6 | +LICENSE file in the root directory of this source tree. |
| 7 | +
|
| 8 | +Unless required by applicable law or agreed to in writing, software |
| 9 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 10 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 11 | +See the License for the specific language governing permissions and |
| 12 | +limitations under the License. |
| 13 | +""" |
| 14 | +import json |
| 15 | +import os |
| 16 | +from typing import Set |
| 17 | + |
| 18 | +exceptions = { |
| 19 | + "proposals/README", |
| 20 | + "proposals/p004_fua-restrict-feature", |
| 21 | + "proposals/p006_subscriber_state_view", |
| 22 | + "proposals/p008_inbound_roaming_with_SubscriberDb", |
| 23 | + "proposals/p006_mandatory_integration_tests_for_each_PR.md", |
| 24 | + "proposals/p010_vendor_neutral_dp", |
| 25 | + "proposals/p011_intra_agw_mobility", |
| 26 | + "proposals/p012_resource-tagging", |
| 27 | + "proposals/sim_integration", |
| 28 | + "proposals/p021_mme_migrate_to_c++", |
| 29 | + "proposals/p022_enodebd_enhancements", |
| 30 | + "proposals/p023_magma_gtp_gateway", |
| 31 | + "proposals/p024_magma_settlement_service", |
| 32 | + "proposals/p025_magma_cdr_availability", |
| 33 | + "proposals/p026_magma_inbound_roaming_extensions", |
| 34 | + "proposals/qos_enforcement", |
| 35 | +} |
| 36 | + |
| 37 | + |
| 38 | +def get_implemented_sidebar_pages(version: str = "latest") -> Set[str]: |
| 39 | + """ |
| 40 | + Scrape the relevant sidebar.json file to get all the pages |
| 41 | + that are implemented in the sidebar. |
| 42 | +
|
| 43 | + Args: |
| 44 | + version (str): The version of the docs to check. Defaults to "latest". |
| 45 | +
|
| 46 | + Returns: |
| 47 | + Set[str]: A set of sidebar pages that are implemented. |
| 48 | + """ |
| 49 | + version_prefix = _get_version_prefix(version) |
| 50 | + implemented_sidebar_pages = _extract_sidebar_pages( |
| 51 | + sidebar_json_path=_get_sidebar_json_path(version), |
| 52 | + version_prefix=version_prefix, |
| 53 | + ) |
| 54 | + implemented_sidebar_pages = _remove_version_prefix( |
| 55 | + implemented_sidebar_pages=implemented_sidebar_pages, |
| 56 | + version_prefix=version_prefix, |
| 57 | + ) |
| 58 | + return implemented_sidebar_pages |
| 59 | + |
| 60 | + |
| 61 | +def get_all_pages(version: str = "latest") -> Set[str]: |
| 62 | + """ |
| 63 | + Scrape the relevant docs folder to get all relevant page ids. |
| 64 | +
|
| 65 | + Args: |
| 66 | + version (str): The version of the docs to check. Defaults to "latest". |
| 67 | +
|
| 68 | + Returns: |
| 69 | + Set[str]: A set of all pages that are available for this version. |
| 70 | + """ |
| 71 | + readme_path = _get_readme_path(version) |
| 72 | + all_pages = set() |
| 73 | + for root, _, filenames in os.walk(readme_path): |
| 74 | + for filename in filenames: |
| 75 | + if filename.endswith('.md'): |
| 76 | + doc_id = _extract_doc_id(filename, root, _get_version_prefix(version)) |
| 77 | + all_pages.add(root.replace(f'{readme_path}/', '') + '/' + doc_id) |
| 78 | + return all_pages |
| 79 | + |
| 80 | + |
| 81 | +def _extract_sidebar_pages(sidebar_json_path, version_prefix): |
| 82 | + implemented_sidebar_pages = set() |
| 83 | + with open(sidebar_json_path) as f: |
| 84 | + sidebars = json.load(f)[f'{version_prefix}docs'] |
| 85 | + for v in sidebars.values(): |
| 86 | + if isinstance(v[0], str): |
| 87 | + implemented_sidebar_pages = implemented_sidebar_pages.union(set(v)) |
| 88 | + else: |
| 89 | + for item in v: |
| 90 | + implemented_sidebar_pages = implemented_sidebar_pages.union(set(item['ids'])) |
| 91 | + return implemented_sidebar_pages |
| 92 | + |
| 93 | + |
| 94 | +def _remove_version_prefix(implemented_sidebar_pages, version_prefix): |
| 95 | + for page in implemented_sidebar_pages: |
| 96 | + if page.startswith(version_prefix): |
| 97 | + implemented_sidebar_pages.remove(page) |
| 98 | + implemented_sidebar_pages.add(page.replace(version_prefix, '')) |
| 99 | + return implemented_sidebar_pages |
| 100 | + |
| 101 | + |
| 102 | +def _get_readme_path(version): |
| 103 | + if version == 'latest': |
| 104 | + return 'readmes' |
| 105 | + return f'docusaurus/versioned_docs/version-{version}' |
| 106 | + |
| 107 | + |
| 108 | +def _get_sidebar_json_path(version): |
| 109 | + if version == 'latest': |
| 110 | + return 'docusaurus/sidebars.json' |
| 111 | + return f'docusaurus/versioned_sidebars/version-{version}-sidebars.json' |
| 112 | + |
| 113 | + |
| 114 | +def _get_version_prefix(version): |
| 115 | + if version == 'latest': |
| 116 | + return '' |
| 117 | + return f'version-{version}-' |
| 118 | + |
| 119 | + |
| 120 | +def _extract_doc_id(filename, root, version_prefix): |
| 121 | + path = os.path.join(root, filename) |
| 122 | + doc_id = "" |
| 123 | + with open(path) as f: |
| 124 | + lines = f.readlines() |
| 125 | + if lines and lines[0].startswith('---'): |
| 126 | + for line in lines: |
| 127 | + if line.startswith('id: '): |
| 128 | + doc_id = line.replace(f'id: {version_prefix}', '').rstrip('\n') |
| 129 | + break |
| 130 | + else: |
| 131 | + doc_id = filename.replace('.md', '') |
| 132 | + return doc_id |
| 133 | + |
| 134 | + |
| 135 | +def main(): |
| 136 | + """ |
| 137 | + Check if all pages are implemented in the sidebar. |
| 138 | + """ |
| 139 | + versions = ("latest", "1.8.0", "1.7.0") |
| 140 | + pages_not_implemented = {v: set() for v in versions} |
| 141 | + for v in versions: |
| 142 | + all_pages = get_all_pages(version=v) |
| 143 | + sidebar_pages = get_implemented_sidebar_pages(version=v) |
| 144 | + for doc in sorted(all_pages): |
| 145 | + if doc not in sidebar_pages.union(exceptions): |
| 146 | + pages_not_implemented[v].add(doc) |
| 147 | + |
| 148 | + sidebars_missing = False |
| 149 | + for v in versions: |
| 150 | + if pages_not_implemented[v]: |
| 151 | + sidebars_missing = True |
| 152 | + print(f"Missing pages for {v}: {pages_not_implemented[v]}") |
| 153 | + if sidebars_missing: |
| 154 | + exit(1) |
| 155 | + |
| 156 | + |
| 157 | +if __name__ == '__main__': |
| 158 | + main() |
0 commit comments