99import subprocess
1010import sys
1111import types
12+ import typing
1213import re
1314from urllib .request import Request , urlopen
1415from urllib .error import HTTPError
@@ -210,6 +211,9 @@ def add_subparser(cls, parent_parser, subparsers):
210211 )
211212 parser .add_argument ("base" , help = "Ex: wpiutil" )
212213 parser .add_argument ("compiled" , nargs = "?" , help = "Ex: wpiutil._impl.wpiutil" )
214+ parser .add_argument (
215+ "--write" , "-w" , action = "store_true" , help = "Modify existing __init__.py"
216+ )
213217 return parser
214218
215219 def _rel (self , base : str , compiled : str ) -> str :
@@ -220,16 +224,18 @@ def _rel(self, base: str, compiled: str) -> str:
220224 return f".{ '.' .join (elems )} "
221225
222226 def run (self , args ):
227+ self .create (args .base , args .compiled , args .write )
228+
229+ def create (self , base : str , compiled : typing .Optional [str ], write : bool ):
223230 # Runtime Dependency Check
224231 try :
225232 import black
226233 except :
227234 print ("Error, The following module is required to run this tool: black" )
228235 exit (1 )
229236
230- compiled = args .compiled
231237 if not compiled :
232- compiled = f"{ args . base } ._{ args . base .split ('.' )[- 1 ]} "
238+ compiled = f"{ base } ._{ base .split ('.' )[- 1 ]} "
233239
234240 # TODO: could probably generate this from parsed code, but seems hard
235241 ctx = {}
@@ -238,25 +244,57 @@ def run(self, args):
238244 if isinstance (ctx [k ], types .ModuleType ):
239245 del ctx [k ]
240246
241- relimport = self ._rel (args . base , compiled )
247+ relimport = self ._rel (base , compiled )
242248
243- stmt_compiled = "" if not args .compiled else f" { args .compiled } "
249+ stmt_compiled = "" if not compiled else f" { compiled } "
250+ begin_stmt = f"# autogenerated by 'robotpy-build create-imports { base } "
244251
245252 stmt = inspect .cleandoc (
246253 f"""
247254
248- # autogenerated by 'robotpy-build create-imports { args . base } { stmt_compiled } '
255+ { begin_stmt } { stmt_compiled } '
249256 from { relimport } import { ',' .join (sorted (ctx .keys ()))}
250257 __all__ = ["{ '", "' .join (sorted (ctx .keys ()))} "]
251258
252259 """
253260 )
254261
255- print (
256- subprocess .check_output (
257- ["black" , "-" , "-q" ], input = stmt .encode ("utf-8" )
258- ).decode ("utf-8" )
259- )
262+ content = subprocess .check_output (
263+ ["black" , "-" , "-q" ], input = stmt .encode ("utf-8" )
264+ ).decode ("utf-8" )
265+
266+ if write :
267+ fctx = {}
268+ exec (f"from { base } import __file__" , {}, fctx )
269+ fname = fctx ["__file__" ]
270+
271+ with open (fname ) as fp :
272+ fcontent = orig_content = fp .read ()
273+
274+ # Find the beginning statement
275+ idx = startidx = fcontent .find (begin_stmt )
276+ if startidx != - 1 :
277+ for to_find in ("from" , "__all__" , "[" , "]" , "\n " ):
278+ idx = fcontent .find (to_find , idx )
279+ if idx == - 1 :
280+ startidx = - 1
281+ break
282+
283+ if startidx == - 1 :
284+ # If not present, just append and let the user figure it out
285+ fcontent = fcontent + "\n " + content
286+ else :
287+ fcontent = fcontent [:startidx ] + content + fcontent [idx + 1 :]
288+
289+ if fcontent != orig_content :
290+ with open (fname , "w" ) as fp :
291+ fp .write (fcontent )
292+ print ("MOD" , base )
293+ else :
294+ print ("OK" , base )
295+
296+ else :
297+ print (content )
260298
261299
262300class PlatformInfo :
0 commit comments