1#!/usr/bin/env 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 directory") 49 sys.exit() 50 51 52# This method uses switcher2, which assumes the refdocs stay in their current 53# asymmetrical dirs (ref/android and ref/kotlin/android) 54# And just puts the switcher in the existing docs 55def insert_stub(doc, java, both): 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 = stubs+1 63 64 if verbose: 65 # Print everything. 66 print("File: ", stubs, doc) 67 else: 68 # Print just the file name on the current line. 69 fn = os.path.split(doc) 70 print("File: ", stubs, fn[1], end="\r") 71 72 if (java): 73 java_stubs = java_stubs + 1 74 else: 75 kotlin_stubs = kotlin_stubs + 1 76 77 78 if (work): 79 if (java): 80 file_path = doc[len(java_ref_root)+1:] 81 stub = doc.replace(java_source_abs_path, kotlin_source_abs_path) 82 # Always add the switcher for java files, switch to the package summary if 83 # the page itself doesn't exist in kotlin 84 slug1 = "sed -i 's/ <div id=\"refdoc-switcher-placeholder\"><\/div>/{}/' {}".format("\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_java_switcher2.md\" %}",doc) 85 else: 86 file_path = doc[len(kotlin_ref_root)+1:] 87 stub = doc.replace(kotlin_source_abs_path, java_source_abs_path) 88 if (both): 89 slug1 = "sed -i 's/ <div id=\"refdoc-switcher-placeholder\"><\/div>/{}/' {}".format("\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc) 90 else: 91 slug1 = "sed -i 's/ <div id=\"refdoc-switcher-placeholder\"><\/div>/{}/' {}".format("\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc) 92 93 os.system(slug1) 94 if both or java: 95 if both: 96 page_path = file_path 97 else: 98 page_path = os.path.join(os.path.dirname(file_path), "package-summary.html") 99 100 page_path_slug = "sed -i 's/_page_path_/{}/' {}".format(page_path.replace("/","\/"),doc) 101 os.system(page_path_slug) 102 103 104def scan_files(stem): 105 global work, verbose, show_solo, max_stubs 106 global stubs 107 global java_stubs, kotlin_stubs 108 global java_source_abs_path 109 global kotlin_source_abs_path 110 111 java_source_abs_path = os.path.join(java_ref_root, stem) 112 kotlin_source_abs_path = os.path.join(kotlin_ref_root, stem) 113 114 # Pass 1 115 # Loop over java content, create stubs for java, 116 # and for corresponding Kotlin (when it exsits) 117 118 # solo is java-only classes 119 # both is java+kotlin 120 stubs = 0 121 java_stubs = 0 122 kotlin_stubs = 0 123 solo = 0 124 both = 0 125 126 print("*** PASS1 (Java) ***") 127 maxed_out = False 128 for root, dirs, files in os.walk(java_source_abs_path): 129 if maxed_out: 130 break; 131 for file_ in files: 132 ext = os.path.splitext(file_) 133 ext = ext[1] 134 if not ext: 135 # this catches package-lists with no extension 136 print("***", os.path.join(root, file_)) 137 elif ext != ".html": 138 # filter out png, yaml, etc 139 continue 140 else: 141 # we have java content 142 doc = os.path.join(root, file_) 143 144 145 146 # look for matching kotlin file 147 kotlinsource = doc.replace(java_source_abs_path, kotlin_source_abs_path) 148 if os.path.isfile(kotlinsource): 149 # corresponding kotlin content exists 150 insert_stub(doc, True, True) 151 insert_stub(kotlinsource, False, True) 152 both = both+1 153 else: 154 # no kotlin content 155 if (show_solo): 156 print("solo: ", doc) 157 insert_stub(doc, True, False) 158 solo = solo+1 159 160 if max_stubs>0 and stubs>=max_stubs: 161 print 162 print("max java stubs: ", max_stubs) 163 maxed_out = True; 164 break 165 print("") 166 print("Java+Kotlin:", both, "Only Java:", solo) 167 print("") 168 169 170 # PASS 2 171 # Loop over kotlin content, create stubs for Kotlin-only APIs 172 print("*** PASS2 (Kotlin) ***") 173 solo = 0 174 both = 0 175 maxed_out = False 176 stubs = 0 177 for root, dirs, files in os.walk(kotlin_source_abs_path): 178 if maxed_out: 179 break; 180 for file_ in files: 181 ext = os.path.splitext (file_) 182 ext = ext[1] 183 if not ext: 184 # this catches package-lists with no extension 185 print("***", os.path.join(root, file_)) 186 elif ext != ".html": 187 # filter out png, yaml, etc 188 continue 189 else: 190 # we have kotlin content 191 doc = os.path.join(root, file_) 192 javadoc = doc.replace(kotlin_source_abs_path, java_source_abs_path) 193 file_name = os.path.splitext(file_)[0] 194 file_path = doc[len(kotlin_source_abs_path)+1:] 195 include_path = os.path.join("/reference/_kotlin", file_path) 196 197 if os.path.isfile(javadoc): 198 # corresponding java content exists 199 # so we already created the kotlin stub file 200 # nothing to do 201 both = both+1 202 else: 203 # no java content 204 # create the kotlin stub file 205 if (show_solo): 206 print("solo: ", doc) 207 insert_stub(doc , False, False) 208 solo = solo+1 209 210 if (max_stubs>0 and stubs>=max_stubs): 211 print 212 print("max koltin stubs: ", max_stubs) 213 maxed_out = True; 214 break 215 216 print("") 217 print("Java+Kotlin:", both, "Only Kotlin:", solo) 218 print("Java: ", java_stubs, " Kotlin: ", kotlin_stubs, "Total: ", java_stubs + kotlin_stubs) 219 220def main(argv): 221 222 global work, verbose, show_solo, max_stubs 223 global java_source_abs_path 224 global kotlin_source_abs_path 225 stem = "" 226 227 try: 228 opts, args = getopt.getopt(argv,"",["work","verbose","solo","max="]) 229 except getopt.GetoptError: 230 print('USAGE: switcher --work --verbose --solo --max=<max_stubs> platform|androidx|support|chrome') 231 sys.exit(2) 232 233 for opt, arg in opts: 234 if opt == '--work': 235 work = True 236 elif opt == "--verbose": 237 print("verbose") 238 verbose = True 239 elif opt == "--solo": 240 print("verbose") 241 show_solo = True 242 elif opt == "--max": 243 max_stubs = int(arg) 244 print("max ", max_stubs) 245 246 if len(args)>0: 247 source = args[0] 248 if source == "platform": 249 stem = "android" 250 print 251 print("*** PLATFORM PAGES ***") 252 print("======================") 253 254 elif source == "androidx": 255 stem = "androidx" 256 print 257 print("*** ANDROIDX SUPPORT LIBRARY PAGES ***") 258 print("======================================") 259 260 elif source == "support": 261 stem = "android/support/v4/media" 262 print 263 print("*** ANDROIDX SUPPORT LIBRARY PAGES ***") 264 print("======================================") 265 266 elif source == "chrome": 267 stem = "org/chromium/support_lib_boundary" 268 print 269 print("*** ANDROIDX CHROMIUM PAGES ***") 270 print("===============================") 271 272 if (len(stem)>0): 273 scan_files(stem) 274 print("") 275 print(" *** DONE ***") 276 else: 277 print('You must specify one of: platform|androidx|support|chrome') 278 279 280 281if __name__ == "__main__": 282 main(sys.argv[1:]) 283 284