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