1#!/usr/bin/python 2# 3# Copyright 2019 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17############################################################################### 18# This script adds a HTML snippet to the generated reference docs located at 19# developer.android.com/reference. The snippet renders HTML that adds links to 20# toggle between the Java and Kotlin versions of the page. 21############################################################################### 22 23import getopt 24import os 25import sys 26 27 28# GLOBAL FLAGS 29 30global stubs 31global java_stubs, kotlin_stubs 32global work, verbose, show_solo, max_stubs 33global java_source_abs_path 34global kotlin_source_abs_path 35 36verbose = False # set True to list all files as they are stubbed (--verbose) 37work = False # set True to insert stubs, False to do a dry run for stats (--work) 38show_solo = False # set True to list files that only appear in one language, rather than both (--solo) 39max_stubs = 0 # set positive to create a limited number of stubs (--max 12) 40 41 42# You must run the script from the refodcs reference/ root directory 43 44java_ref_root = os.getcwd() 45kotlin_ref_root = os.path.join(java_ref_root, "kotlin") 46root = os.path.split(java_ref_root)[1] 47if root != "reference": 48 print ("You must cd to the refocs reference/ root directoy") 49 sys.exit() 50 51 52# This method inserts the language switcher into the two top-level Android 53# Platform pages: packages.html and classes.html 54# For both Java and Kotlin 55def insert_platform_summaries(): 56 global stubs 57 global java_stubs, kotlin_stubs 58 global verbose, work, show_solo 59 global java_source_abs_path 60 global kotlin_source_abs_path 61 62 stubs = 0 63 java_stubs = 0 64 kotlin_stubs = 0 65 66 java_source_abs_path = java_ref_root 67 kotlin_source_abs_path = kotlin_ref_root 68 insert_stub(os.path.join(java_ref_root, "packages.html"), True, True) 69 insert_stub(os.path.join(kotlin_ref_root, "packages.html"), False, True) 70 71 insert_stub(os.path.join(java_ref_root, "classes.html"), True, True) 72 insert_stub(os.path.join(kotlin_ref_root, "classes.html"), False, True) 73 74# This method uses switcher2, which assumes the refdocs stay in their current 75# assymetrical dirs (ref/android and ref/kotlin/android) 76# And just puts the switcher in the existing docs 77def insert_stub(doc, java, both): 78 global stubs 79 global java_stubs, kotlin_stubs 80 global verbose, work, show_solo 81 global java_source_abs_path 82 global kotlin_source_abs_path 83 84 stubs = stubs+1 85 86 if verbose: 87 print "File: ", stubs, doc 88 else: 89 fn = os.path.split(doc) 90 print "File: ", stubs, fn[1], "\r", 91 92 if (java): 93 java_stubs = java_stubs + 1 94 else: 95 kotlin_stubs = kotlin_stubs + 1 96 97 98 if (work): 99 if (java): 100 file_path = doc[len(java_ref_root)+1:] 101 stub = doc.replace(java_source_abs_path, kotlin_source_abs_path) 102 if (both): 103 slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_java_switcher2.md\" %}",doc) 104 else: 105 slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% include \"reference\/_java_switcher2.md\" %}",doc) 106 else: 107 file_path = doc[len(kotlin_ref_root)+1:] 108 stub = doc.replace(kotlin_source_abs_path, java_source_abs_path) 109 if (both): 110 slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc) 111 else: 112 slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc) 113 114 os.system(slug1) 115 if (both): 116 page_path_slug = "sed -i 's/_page_path_/{}/' {}".format(file_path.replace("/","\/"),doc) 117 os.system(page_path_slug) 118 119 120def scan_files(stem): 121 global work, verbose, show_solo, max_stubs 122 global stubs 123 global java_stubs, kotlin_stubs 124 global java_source_abs_path 125 global kotlin_source_abs_path 126 127 java_source_abs_path = os.path.join(java_ref_root, stem) 128 kotlin_source_abs_path = os.path.join(kotlin_ref_root, stem) 129 130 # Pass 1 131 # Loop over java content, create stubs for java, 132 # and for corresponding Kotlin (when it exsits) 133 134 # solo is java-only classes 135 # both is java+kotlin 136 stubs = 0 137 java_stubs = 0 138 kotlin_stubs = 0 139 solo = 0 140 both = 0 141 142 print "*** PASS1 (Java) ***" 143 maxed_out = False 144 for root, dirs, files in os.walk(java_source_abs_path): 145 if maxed_out: 146 break; 147 for file_ in files: 148 ext = os.path.splitext(file_) 149 ext = ext[1] 150 if not ext: 151 # this catches package-lists with no extension 152 print "***", os.path.join(root, file_) 153 elif ext != ".html": 154 # filter out png, yaml, etc 155 continue 156 else: 157 # we have java content 158 doc = os.path.join(root, file_) 159 160 161 162 # look for matching kotlin file 163 kotlinsource = doc.replace(java_source_abs_path, kotlin_source_abs_path) 164 if os.path.isfile(kotlinsource): 165 # corresponding kotlin content exists 166 insert_stub(doc, True, True) 167 insert_stub(kotlinsource, False, True) 168 both = both+1 169 else: 170 # no kotlin content 171 if (show_solo): 172 print "solo: ", doc 173 insert_stub(doc, True, False) 174 solo = solo+1 175 176 if max_stubs>0 and stubs>=max_stubs: 177 print 178 print "max java stubs: ", max_stubs 179 maxed_out = True; 180 break 181 182 print "Java+Kotlin:", both, "Only Java:", solo 183 print 184 185 186 # PASS 2 187 # Loop over kotlin content, create stubs for Kotlin-only APIs 188 print "*** PASS2 (Kotlin) ***" 189 solo = 0 190 both = 0 191 maxed_out = False 192 stubs = 0 193 for root, dirs, files in os.walk(kotlin_source_abs_path): 194 if maxed_out: 195 break; 196 for file_ in files: 197 ext = os.path.splitext (file_) 198 ext = ext[1] 199 if not ext: 200 # this catches package-lists with no extension 201 print "***", os.path.join(root, file_) 202 elif ext != ".html": 203 # filter out png, yaml, etc 204 continue 205 else: 206 # we have kotlin content 207 doc = os.path.join(root, file_) 208 javadoc = doc.replace(kotlin_source_abs_path, java_source_abs_path) 209 file_name = os.path.splitext(file_)[0] 210 file_path = doc[len(kotlin_source_abs_path)+1:] 211 include_path = os.path.join("/reference/_kotlin", file_path) 212 213 if os.path.isfile(javadoc): 214 # corresponding java content exists 215 # so we already created the kotlin stub file 216 # nothing to do 217 both = both+1 218 else: 219 # no java content 220 # create the kotlin stub file 221 if (show_solo): 222 print "solo: ", doc 223 insert_stub(doc , False, False) 224 solo = solo+1 225 226 if (max_stubs>0 and stubs>=max_stubs): 227 print 228 print "max koltin stubs: ", max_stubs 229 maxed_out = True; 230 break 231 232 233 print "Java+Kotlin:", both, "Only Kotlin:", solo 234 print 235 print "Java: ", java_stubs, " Kotlin: ", kotlin_stubs, "Total: ", java_stubs + kotlin_stubs 236 237 238def main(argv): 239 240 global work, verbose, show_solo, max_stubs 241 global java_source_abs_path 242 global kotlin_source_abs_path 243 stem = "" 244 245 try: 246 opts, args = getopt.getopt(argv,"",["work","verbose","solo","max="]) 247 except getopt.GetoptError: 248 print 'USAGE: switcher --work --verbose --solo --max=<max_stubs> platform|androidx|support|chrome' 249 sys.exit(2) 250 251 for opt, arg in opts: 252 if opt == '--work': 253 work = True 254 elif opt == "--verbose": 255 print "verbose" 256 verbose = True 257 elif opt == "--solo": 258 print "verbose" 259 show_solo = True 260 elif opt == "--max": 261 max_stubs = int(arg) 262 print "max ", max_stubs 263 264 if len(args)>0: 265 source = args[0] 266 if source == "platform": 267 stem = "android" 268 print 269 print "*** PLATFORM PAGES ***" 270 print "======================" 271 272 # Insert the switchers at the top level first 273 insert_platform_summaries() 274 275 elif source == "androidx": 276 stem = "androidx" 277 print 278 print "*** ANDROIDX SUPPORT LIBRARY PAGES ***" 279 print "======================================" 280 281 elif source == "support": 282 stem = "android/support/v4/media" 283 print 284 print "*** ANDROIDX SUPPORT LIBRARY PAGES ***" 285 print "======================================" 286 287 elif source == "chrome": 288 stem = "org/chromium/support_lib_boundary" 289 print 290 print "*** ANDROIDX CHROMIUM PAGES ***" 291 print "===============================" 292 293 if (len(stem)>0): 294 scan_files(stem) 295 print " *** DONE ***" 296 else: 297 print 'You must specify one of: platform|androidx|support|chrome' 298 299 300 301if __name__ == "__main__": 302 main(sys.argv[1:]) 303 304