1*9880d681SAndroid Build Coastguard Worker""" 2*9880d681SAndroid Build Coastguard WorkerDefines utilities useful for performing standard "configuration" style tasks. 3*9880d681SAndroid Build Coastguard Worker""" 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerimport re 6*9880d681SAndroid Build Coastguard Workerimport os 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdef configure_file(input_path, output_path, substitutions): 9*9880d681SAndroid Build Coastguard Worker """configure_file(input_path, output_path, substitutions) -> bool 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Worker Given an input and output path, "configure" the file at the given input path 12*9880d681SAndroid Build Coastguard Worker by replacing variables in the file with those given in the substitutions 13*9880d681SAndroid Build Coastguard Worker list. Returns true if the output file was written. 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker The substitutions list should be given as a list of tuples (regex string, 16*9880d681SAndroid Build Coastguard Worker replacement), where the regex and replacement will be used as in 're.sub' to 17*9880d681SAndroid Build Coastguard Worker execute the variable replacement. 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker The output path's parent directory need not exist (it will be created). 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker If the output path does exist and the configured data is not different than 22*9880d681SAndroid Build Coastguard Worker it's current contents, the output file will not be modified. This is 23*9880d681SAndroid Build Coastguard Worker designed to limit the impact of configured files on build dependencies. 24*9880d681SAndroid Build Coastguard Worker """ 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker # Read in the input data. 27*9880d681SAndroid Build Coastguard Worker f = open(input_path, "rb") 28*9880d681SAndroid Build Coastguard Worker try: 29*9880d681SAndroid Build Coastguard Worker data = f.read() 30*9880d681SAndroid Build Coastguard Worker finally: 31*9880d681SAndroid Build Coastguard Worker f.close() 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker # Perform the substitutions. 34*9880d681SAndroid Build Coastguard Worker for regex_string,replacement in substitutions: 35*9880d681SAndroid Build Coastguard Worker regex = re.compile(regex_string) 36*9880d681SAndroid Build Coastguard Worker data = regex.sub(replacement, data) 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker # Ensure the output parent directory exists. 39*9880d681SAndroid Build Coastguard Worker output_parent_path = os.path.dirname(os.path.abspath(output_path)) 40*9880d681SAndroid Build Coastguard Worker if not os.path.exists(output_parent_path): 41*9880d681SAndroid Build Coastguard Worker os.makedirs(output_parent_path) 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker # If the output path exists, load it and compare to the configured contents. 44*9880d681SAndroid Build Coastguard Worker if os.path.exists(output_path): 45*9880d681SAndroid Build Coastguard Worker current_data = None 46*9880d681SAndroid Build Coastguard Worker try: 47*9880d681SAndroid Build Coastguard Worker f = open(output_path, "rb") 48*9880d681SAndroid Build Coastguard Worker try: 49*9880d681SAndroid Build Coastguard Worker current_data = f.read() 50*9880d681SAndroid Build Coastguard Worker except: 51*9880d681SAndroid Build Coastguard Worker current_data = None 52*9880d681SAndroid Build Coastguard Worker f.close() 53*9880d681SAndroid Build Coastguard Worker except: 54*9880d681SAndroid Build Coastguard Worker current_data = None 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker if current_data is not None and current_data == data: 57*9880d681SAndroid Build Coastguard Worker return False 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker # Write the output contents. 60*9880d681SAndroid Build Coastguard Worker f = open(output_path, "wb") 61*9880d681SAndroid Build Coastguard Worker try: 62*9880d681SAndroid Build Coastguard Worker f.write(data) 63*9880d681SAndroid Build Coastguard Worker finally: 64*9880d681SAndroid Build Coastguard Worker f.close() 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker return True 67