| # Copyright 2020 Google LLC | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """This script is used to synthesize generated parts of this library.""" | |
| from typing import List, Optional | |
| from glob import glob | |
| import json | |
| import requests | |
| class CloudClient: | |
| repo: str = None | |
| title: str = None | |
| release_level: str = None | |
| group_id: str = "com.google.cloud" | |
| artifact_id: str = None | |
| def __init__(self, repo: dict): | |
| self.repo = repo['repo'] | |
| # For now, strip out "Google Cloud" to standardize the titles | |
| self.title = repo['name_pretty'].replace("Google ", "").replace("Cloud ", "") | |
| self.release_level = repo['release_level'] | |
| artifact_parts = repo['distribution_name'].split(':') | |
| if len(artifact_parts) > 1: | |
| self.group_id = artifact_parts[0] | |
| self.artifact_id = artifact_parts[1] | |
| else: | |
| self.artifact_id = repo['distribution_name'] | |
| # For sorting, we want to sort by release level, then API pretty_name | |
| def __lt__(self, other): | |
| if self.release_level == other.release_level: | |
| return self.title < other.title | |
| return other.release_level < self.release_level | |
| def __repr__(self): | |
| return repr((self.release_level, self.title)) | |
| def replace_content_in_readme(content_rows: List[str]) -> None: | |
| START_MARKER = "[//]: # (API_TABLE_START)" | |
| END_MARKER = "[//]: # (API_TABLE_END)" | |
| newlines = [] | |
| repl_open = False | |
| with open("README.md", "r") as f: | |
| for line in f: | |
| if not repl_open: | |
| newlines.append(line) | |
| if line.startswith(START_MARKER): | |
| repl_open = True | |
| newlines = newlines + content_rows | |
| elif line.startswith(END_MARKER): | |
| newlines.append("\n") | |
| newlines.append(line) | |
| repl_open = False | |
| with open("README.md", "w") as f: | |
| for line in newlines: | |
| f.write(line) | |
| RELEASE_LEVEL_CONTENT = { | |
| "preview": "[![preview][preview-stability]][preview-description]", | |
| "stable": "[![stable][stable-stability]][stable-description]" | |
| } | |
| def client_row(client: CloudClient) -> str: | |
| maven_badge = f"[](https://search.maven.org/search?q=g:{client.group_id}%20AND%20a:{client.artifact_id}&core=gav)" | |
| return f"| [{client.title}](https://github.com/{client.repo}) | {RELEASE_LEVEL_CONTENT[client.release_level]} | {maven_badge} |\n" | |
| def generate_table_contents(clients: List[CloudClient]) -> List[str]: | |
| content_rows = [ | |
| "\n", | |
| "| Client | Release Level | Version |\n", | |
| "| ------ | ------------- | ------- |\n", | |
| ] | |
| return content_rows + [client_row(client) for client in clients] | |
| REPO_METADATA_URL_FORMAT = "https://raw.githubusercontent.com/{repo_slug}/main/.repo-metadata.json" | |
| def client_for_repo(repo_slug) -> Optional[CloudClient]: | |
| url = REPO_METADATA_URL_FORMAT.format(repo_slug=repo_slug) | |
| response = requests.get(url) | |
| if response.status_code != requests.codes.ok: | |
| return | |
| return CloudClient(response.json()) | |
| def client_for_module(module) -> Optional[CloudClient]: | |
| with open ('%s/.repo-metadata.json' % module, "r") as metadata_file: | |
| data = json.load(metadata_file) | |
| data['repo'] = 'googleapis/google-cloud-java/tree/main/%s' % module | |
| return CloudClient(data) | |
| # These repositories are not meant as shown as Cloud SDK for Java | |
| REPO_EXCLUSION = [ | |
| 'java-bigtable-emulator', | |
| 'java-cloud-bom', | |
| 'java-conformance-tests', | |
| 'java-common-protos', | |
| 'java-core', | |
| 'java-gcloud-maven-plugin', | |
| 'java-grafeas', | |
| 'java-notification', | |
| 'java-shared-config', | |
| 'java-shared-dependencies' | |
| ] | |
| LIBRARIES_IN_MONOREPO = glob("java-*") | |
| def allowed_remote_repo(repo) -> bool: | |
| return (repo['language'].lower() == 'java' | |
| and repo['full_name'].startswith('googleapis/java-') | |
| and repo['full_name'] not in | |
| [ 'googleapis/%s' % repo for repo in (REPO_EXCLUSION + LIBRARIES_IN_MONOREPO)]) | |
| def _fetch_repo_list(page): | |
| url = "https://api.github.com/search/repositories" | |
| response = requests.get(url, params = { | |
| 'q': 'org:googleapis is:public archived:false language:java', | |
| 'per_page': 100, | |
| 'page': page, | |
| }) | |
| return response.json()['items'] | |
| def all_clients() -> List[CloudClient]: | |
| page = 1 | |
| clients = [] | |
| while (True): | |
| repos = _fetch_repo_list(page) | |
| if not repos: | |
| break | |
| clients.extend([client_for_repo(repo['full_name']) for repo in repos if allowed_remote_repo(repo)]) | |
| page += 1 | |
| clients.extend([client_for_module(module) for module in LIBRARIES_IN_MONOREPO if | |
| module not in REPO_EXCLUSION]) | |
| return [client for client in clients if client] | |
| clients = sorted(all_clients()) | |
| table_contents = generate_table_contents(clients) | |
| replace_content_in_readme(table_contents) |