xref: /aosp_15_r20/external/google-cloud-java/generate-readme.py (revision 55e87721aa1bc457b326496a7ca40f3ea1a63287)
1*55e87721SMatt Gilbride# Copyright 2020 Google LLC
2*55e87721SMatt Gilbride#
3*55e87721SMatt Gilbride# Licensed under the Apache License, Version 2.0 (the "License");
4*55e87721SMatt Gilbride# you may not use this file except in compliance with the License.
5*55e87721SMatt Gilbride# You may obtain a copy of the License at
6*55e87721SMatt Gilbride#
7*55e87721SMatt Gilbride#     http://www.apache.org/licenses/LICENSE-2.0
8*55e87721SMatt Gilbride#
9*55e87721SMatt Gilbride# Unless required by applicable law or agreed to in writing, software
10*55e87721SMatt Gilbride# distributed under the License is distributed on an "AS IS" BASIS,
11*55e87721SMatt Gilbride# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*55e87721SMatt Gilbride# See the License for the specific language governing permissions and
13*55e87721SMatt Gilbride# limitations under the License.
14*55e87721SMatt Gilbride
15*55e87721SMatt Gilbride"""This script is used to synthesize generated parts of this library."""
16*55e87721SMatt Gilbride
17*55e87721SMatt Gilbridefrom typing import List, Optional
18*55e87721SMatt Gilbridefrom glob import glob
19*55e87721SMatt Gilbrideimport json
20*55e87721SMatt Gilbrideimport requests
21*55e87721SMatt Gilbride
22*55e87721SMatt Gilbrideclass CloudClient:
23*55e87721SMatt Gilbride  repo: str = None
24*55e87721SMatt Gilbride  title: str = None
25*55e87721SMatt Gilbride  release_level: str = None
26*55e87721SMatt Gilbride  group_id: str = "com.google.cloud"
27*55e87721SMatt Gilbride  artifact_id: str = None
28*55e87721SMatt Gilbride
29*55e87721SMatt Gilbride  def __init__(self, repo: dict):
30*55e87721SMatt Gilbride    self.repo = repo['repo']
31*55e87721SMatt Gilbride    # For now, strip out "Google Cloud" to standardize the titles
32*55e87721SMatt Gilbride    self.title = repo['name_pretty'].replace("Google ", "").replace("Cloud ", "")
33*55e87721SMatt Gilbride    self.release_level = repo['release_level']
34*55e87721SMatt Gilbride    artifact_parts = repo['distribution_name'].split(':')
35*55e87721SMatt Gilbride    if len(artifact_parts) > 1:
36*55e87721SMatt Gilbride      self.group_id = artifact_parts[0]
37*55e87721SMatt Gilbride      self.artifact_id = artifact_parts[1]
38*55e87721SMatt Gilbride    else:
39*55e87721SMatt Gilbride      self.artifact_id = repo['distribution_name']
40*55e87721SMatt Gilbride
41*55e87721SMatt Gilbride  # For sorting, we want to sort by release level, then API pretty_name
42*55e87721SMatt Gilbride  def __lt__(self, other):
43*55e87721SMatt Gilbride    if self.release_level == other.release_level:
44*55e87721SMatt Gilbride      return self.title < other.title
45*55e87721SMatt Gilbride
46*55e87721SMatt Gilbride    return other.release_level < self.release_level
47*55e87721SMatt Gilbride
48*55e87721SMatt Gilbride  def __repr__(self):
49*55e87721SMatt Gilbride    return repr((self.release_level, self.title))
50*55e87721SMatt Gilbride
51*55e87721SMatt Gilbridedef replace_content_in_readme(content_rows: List[str]) -> None:
52*55e87721SMatt Gilbride  START_MARKER = "[//]: # (API_TABLE_START)"
53*55e87721SMatt Gilbride  END_MARKER = "[//]: # (API_TABLE_END)"
54*55e87721SMatt Gilbride  newlines = []
55*55e87721SMatt Gilbride  repl_open = False
56*55e87721SMatt Gilbride  with open("README.md", "r") as f:
57*55e87721SMatt Gilbride    for line in f:
58*55e87721SMatt Gilbride      if not repl_open:
59*55e87721SMatt Gilbride        newlines.append(line)
60*55e87721SMatt Gilbride
61*55e87721SMatt Gilbride      if line.startswith(START_MARKER):
62*55e87721SMatt Gilbride        repl_open = True
63*55e87721SMatt Gilbride        newlines = newlines + content_rows
64*55e87721SMatt Gilbride      elif line.startswith(END_MARKER):
65*55e87721SMatt Gilbride        newlines.append("\n")
66*55e87721SMatt Gilbride        newlines.append(line)
67*55e87721SMatt Gilbride        repl_open = False
68*55e87721SMatt Gilbride
69*55e87721SMatt Gilbride  with open("README.md", "w") as f:
70*55e87721SMatt Gilbride    for line in newlines:
71*55e87721SMatt Gilbride      f.write(line)
72*55e87721SMatt Gilbride
73*55e87721SMatt GilbrideRELEASE_LEVEL_CONTENT = {
74*55e87721SMatt Gilbride  "preview": "[![preview][preview-stability]][preview-description]",
75*55e87721SMatt Gilbride  "stable": "[![stable][stable-stability]][stable-description]"
76*55e87721SMatt Gilbride}
77*55e87721SMatt Gilbride
78*55e87721SMatt Gilbridedef client_row(client: CloudClient) -> str:
79*55e87721SMatt Gilbride  maven_badge = f"[![Maven](https://img.shields.io/maven-central/v/{client.group_id}/{client.artifact_id}.svg)](https://search.maven.org/search?q=g:{client.group_id}%20AND%20a:{client.artifact_id}&core=gav)"
80*55e87721SMatt Gilbride  return f"| [{client.title}](https://github.com/{client.repo}) | {RELEASE_LEVEL_CONTENT[client.release_level]} | {maven_badge} |\n"
81*55e87721SMatt Gilbride
82*55e87721SMatt Gilbridedef generate_table_contents(clients: List[CloudClient]) -> List[str]:
83*55e87721SMatt Gilbride  content_rows = [
84*55e87721SMatt Gilbride    "\n",
85*55e87721SMatt Gilbride    "| Client | Release Level | Version |\n",
86*55e87721SMatt Gilbride    "| ------ | ------------- | ------- |\n",
87*55e87721SMatt Gilbride  ]
88*55e87721SMatt Gilbride  return content_rows + [client_row(client) for client in clients]
89*55e87721SMatt Gilbride
90*55e87721SMatt Gilbride
91*55e87721SMatt GilbrideREPO_METADATA_URL_FORMAT = "https://raw.githubusercontent.com/{repo_slug}/main/.repo-metadata.json"
92*55e87721SMatt Gilbride
93*55e87721SMatt Gilbridedef client_for_repo(repo_slug) -> Optional[CloudClient]:
94*55e87721SMatt Gilbride  url = REPO_METADATA_URL_FORMAT.format(repo_slug=repo_slug)
95*55e87721SMatt Gilbride  response = requests.get(url)
96*55e87721SMatt Gilbride  if response.status_code != requests.codes.ok:
97*55e87721SMatt Gilbride    return
98*55e87721SMatt Gilbride
99*55e87721SMatt Gilbride  return CloudClient(response.json())
100*55e87721SMatt Gilbride
101*55e87721SMatt Gilbridedef client_for_module(module) -> Optional[CloudClient]:
102*55e87721SMatt Gilbride  with open ('%s/.repo-metadata.json' % module, "r") as metadata_file:
103*55e87721SMatt Gilbride    data = json.load(metadata_file)
104*55e87721SMatt Gilbride    data['repo'] = 'googleapis/google-cloud-java/tree/main/%s' % module
105*55e87721SMatt Gilbride    return CloudClient(data)
106*55e87721SMatt Gilbride
107*55e87721SMatt Gilbride# These repositories are not meant as shown as Cloud SDK for Java
108*55e87721SMatt GilbrideREPO_EXCLUSION = [
109*55e87721SMatt Gilbride  'java-bigtable-emulator',
110*55e87721SMatt Gilbride  'java-cloud-bom',
111*55e87721SMatt Gilbride  'java-conformance-tests',
112*55e87721SMatt Gilbride  'java-common-protos',
113*55e87721SMatt Gilbride  'java-core',
114*55e87721SMatt Gilbride  'java-gcloud-maven-plugin',
115*55e87721SMatt Gilbride  'java-grafeas',
116*55e87721SMatt Gilbride  'java-notification',
117*55e87721SMatt Gilbride  'java-shared-config',
118*55e87721SMatt Gilbride  'java-shared-dependencies'
119*55e87721SMatt Gilbride]
120*55e87721SMatt Gilbride
121*55e87721SMatt GilbrideLIBRARIES_IN_MONOREPO = glob("java-*")
122*55e87721SMatt Gilbride
123*55e87721SMatt Gilbridedef allowed_remote_repo(repo) -> bool:
124*55e87721SMatt Gilbride  return (repo['language'].lower() == 'java'
125*55e87721SMatt Gilbride          and repo['full_name'].startswith('googleapis/java-')
126*55e87721SMatt Gilbride          and repo['full_name'] not in
127*55e87721SMatt Gilbride          [ 'googleapis/%s' % repo for repo in (REPO_EXCLUSION + LIBRARIES_IN_MONOREPO)])
128*55e87721SMatt Gilbride
129*55e87721SMatt Gilbridedef _fetch_repo_list(page):
130*55e87721SMatt Gilbride  url = "https://api.github.com/search/repositories"
131*55e87721SMatt Gilbride  response = requests.get(url, params = {
132*55e87721SMatt Gilbride    'q': 'org:googleapis is:public archived:false language:java',
133*55e87721SMatt Gilbride    'per_page': 100,
134*55e87721SMatt Gilbride    'page': page,
135*55e87721SMatt Gilbride  })
136*55e87721SMatt Gilbride  return response.json()['items']
137*55e87721SMatt Gilbride
138*55e87721SMatt Gilbridedef all_clients() -> List[CloudClient]:
139*55e87721SMatt Gilbride  page = 1
140*55e87721SMatt Gilbride  clients = []
141*55e87721SMatt Gilbride  while (True):
142*55e87721SMatt Gilbride    repos = _fetch_repo_list(page)
143*55e87721SMatt Gilbride    if not repos:
144*55e87721SMatt Gilbride      break
145*55e87721SMatt Gilbride    clients.extend([client_for_repo(repo['full_name']) for repo in repos if allowed_remote_repo(repo)])
146*55e87721SMatt Gilbride    page += 1
147*55e87721SMatt Gilbride  clients.extend([client_for_module(module) for module in LIBRARIES_IN_MONOREPO if
148*55e87721SMatt Gilbride                  module not in REPO_EXCLUSION])
149*55e87721SMatt Gilbride
150*55e87721SMatt Gilbride  return [client for client in clients if client]
151*55e87721SMatt Gilbride
152*55e87721SMatt Gilbride
153*55e87721SMatt Gilbrideclients = sorted(all_clients())
154*55e87721SMatt Gilbridetable_contents = generate_table_contents(clients)
155*55e87721SMatt Gilbridereplace_content_in_readme(table_contents)
156