1*d9f75844SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*d9f75844SAndroid Build Coastguard Worker# 3*d9f75844SAndroid Build Coastguard Worker# Copyright 2021 The Abseil Authors. 4*d9f75844SAndroid Build Coastguard Worker# 5*d9f75844SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*d9f75844SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*d9f75844SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*d9f75844SAndroid Build Coastguard Worker# 9*d9f75844SAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 10*d9f75844SAndroid Build Coastguard Worker# 11*d9f75844SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*d9f75844SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*d9f75844SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*d9f75844SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*d9f75844SAndroid Build Coastguard Worker# limitations under the License. 16*d9f75844SAndroid Build Coastguard Worker"""A script to do source transformations to create a new LTS release. 17*d9f75844SAndroid Build Coastguard Worker 18*d9f75844SAndroid Build Coastguard Worker Usage: ./create_lts.py YYYYMMDD 19*d9f75844SAndroid Build Coastguard Worker""" 20*d9f75844SAndroid Build Coastguard Worker 21*d9f75844SAndroid Build Coastguard Workerimport sys 22*d9f75844SAndroid Build Coastguard Worker 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Workerdef ReplaceStringsInFile(filename, replacement_dict): 25*d9f75844SAndroid Build Coastguard Worker """Performs textual replacements in a file. 26*d9f75844SAndroid Build Coastguard Worker 27*d9f75844SAndroid Build Coastguard Worker Rewrites filename with the keys in replacement_dict replaced with 28*d9f75844SAndroid Build Coastguard Worker their values. This function assumes the file can fit in memory. 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker Args: 31*d9f75844SAndroid Build Coastguard Worker filename: the filename to perform the replacement on 32*d9f75844SAndroid Build Coastguard Worker replacement_dict: a dictionary of key strings to be replaced with their 33*d9f75844SAndroid Build Coastguard Worker values 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker Raises: 36*d9f75844SAndroid Build Coastguard Worker Exception: A failure occured 37*d9f75844SAndroid Build Coastguard Worker """ 38*d9f75844SAndroid Build Coastguard Worker f = open(filename, 'r') 39*d9f75844SAndroid Build Coastguard Worker content = f.read() 40*d9f75844SAndroid Build Coastguard Worker f.close() 41*d9f75844SAndroid Build Coastguard Worker 42*d9f75844SAndroid Build Coastguard Worker for key, value in replacement_dict.items(): 43*d9f75844SAndroid Build Coastguard Worker original = content 44*d9f75844SAndroid Build Coastguard Worker content = content.replace(key, value) 45*d9f75844SAndroid Build Coastguard Worker if content == original: 46*d9f75844SAndroid Build Coastguard Worker raise Exception('Failed to find {} in {}'.format(key, filename)) 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker f = open(filename, 'w') 49*d9f75844SAndroid Build Coastguard Worker f.write(content) 50*d9f75844SAndroid Build Coastguard Worker f.close() 51*d9f75844SAndroid Build Coastguard Worker 52*d9f75844SAndroid Build Coastguard Worker 53*d9f75844SAndroid Build Coastguard Workerdef StripContentBetweenTags(filename, strip_begin_tag, strip_end_tag): 54*d9f75844SAndroid Build Coastguard Worker """Strip contents from a file. 55*d9f75844SAndroid Build Coastguard Worker 56*d9f75844SAndroid Build Coastguard Worker Rewrites filename with by removing all content between 57*d9f75844SAndroid Build Coastguard Worker strip_begin_tag and strip_end_tag, including the tags themselves. 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker Args: 60*d9f75844SAndroid Build Coastguard Worker filename: the filename to perform the replacement on 61*d9f75844SAndroid Build Coastguard Worker strip_begin_tag: the start of the content to be removed 62*d9f75844SAndroid Build Coastguard Worker strip_end_tag: the end of the content to be removed 63*d9f75844SAndroid Build Coastguard Worker 64*d9f75844SAndroid Build Coastguard Worker Raises: 65*d9f75844SAndroid Build Coastguard Worker Exception: A failure occured 66*d9f75844SAndroid Build Coastguard Worker """ 67*d9f75844SAndroid Build Coastguard Worker f = open(filename, 'r') 68*d9f75844SAndroid Build Coastguard Worker content = f.read() 69*d9f75844SAndroid Build Coastguard Worker f.close() 70*d9f75844SAndroid Build Coastguard Worker 71*d9f75844SAndroid Build Coastguard Worker while True: 72*d9f75844SAndroid Build Coastguard Worker begin = content.find(strip_begin_tag) 73*d9f75844SAndroid Build Coastguard Worker if begin == -1: 74*d9f75844SAndroid Build Coastguard Worker break 75*d9f75844SAndroid Build Coastguard Worker end = content.find(strip_end_tag, begin + len(strip_begin_tag)) 76*d9f75844SAndroid Build Coastguard Worker if end == -1: 77*d9f75844SAndroid Build Coastguard Worker raise Exception('{}: imbalanced strip begin ({}) and ' 78*d9f75844SAndroid Build Coastguard Worker 'end ({}) tags'.format(filename, strip_begin_tag, 79*d9f75844SAndroid Build Coastguard Worker strip_end_tag)) 80*d9f75844SAndroid Build Coastguard Worker content = content.replace(content[begin:end + len(strip_end_tag)], '') 81*d9f75844SAndroid Build Coastguard Worker 82*d9f75844SAndroid Build Coastguard Worker f = open(filename, 'w') 83*d9f75844SAndroid Build Coastguard Worker f.write(content) 84*d9f75844SAndroid Build Coastguard Worker f.close() 85*d9f75844SAndroid Build Coastguard Worker 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Workerdef main(argv): 88*d9f75844SAndroid Build Coastguard Worker if len(argv) != 2: 89*d9f75844SAndroid Build Coastguard Worker print('Usage: {} YYYYMMDD'.format(sys.argv[0], file=sys.stderr)) 90*d9f75844SAndroid Build Coastguard Worker sys.exit(1) 91*d9f75844SAndroid Build Coastguard Worker 92*d9f75844SAndroid Build Coastguard Worker datestamp = sys.argv[1] 93*d9f75844SAndroid Build Coastguard Worker if len(datestamp) != 8 or not datestamp.isdigit(): 94*d9f75844SAndroid Build Coastguard Worker raise Exception( 95*d9f75844SAndroid Build Coastguard Worker 'datestamp={} is not in the YYYYMMDD format'.format(datestamp)) 96*d9f75844SAndroid Build Coastguard Worker 97*d9f75844SAndroid Build Coastguard Worker # Replacement directives go here. 98*d9f75844SAndroid Build Coastguard Worker ReplaceStringsInFile( 99*d9f75844SAndroid Build Coastguard Worker 'absl/base/config.h', { 100*d9f75844SAndroid Build Coastguard Worker '#undef ABSL_LTS_RELEASE_VERSION': 101*d9f75844SAndroid Build Coastguard Worker '#define ABSL_LTS_RELEASE_VERSION {}'.format(datestamp), 102*d9f75844SAndroid Build Coastguard Worker '#undef ABSL_LTS_RELEASE_PATCH_LEVEL': 103*d9f75844SAndroid Build Coastguard Worker '#define ABSL_LTS_RELEASE_PATCH_LEVEL 0' 104*d9f75844SAndroid Build Coastguard Worker }) 105*d9f75844SAndroid Build Coastguard Worker ReplaceStringsInFile( 106*d9f75844SAndroid Build Coastguard Worker 'absl/base/options.h', { 107*d9f75844SAndroid Build Coastguard Worker '#define ABSL_OPTION_USE_INLINE_NAMESPACE 0': 108*d9f75844SAndroid Build Coastguard Worker '#define ABSL_OPTION_USE_INLINE_NAMESPACE 1', 109*d9f75844SAndroid Build Coastguard Worker '#define ABSL_OPTION_INLINE_NAMESPACE_NAME head': 110*d9f75844SAndroid Build Coastguard Worker '#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_{}'.format( 111*d9f75844SAndroid Build Coastguard Worker datestamp) 112*d9f75844SAndroid Build Coastguard Worker }) 113*d9f75844SAndroid Build Coastguard Worker ReplaceStringsInFile( 114*d9f75844SAndroid Build Coastguard Worker 'CMakeLists.txt', { 115*d9f75844SAndroid Build Coastguard Worker 'project(absl LANGUAGES CXX)': 116*d9f75844SAndroid Build Coastguard Worker 'project(absl LANGUAGES CXX VERSION {})'.format(datestamp) 117*d9f75844SAndroid Build Coastguard Worker }) 118*d9f75844SAndroid Build Coastguard Worker # Set the SOVERSION to YYMM.0.0 - The first 0 means we only have ABI 119*d9f75844SAndroid Build Coastguard Worker # compatible changes, and the second 0 means we can increment it to 120*d9f75844SAndroid Build Coastguard Worker # mark changes as ABI-compatible, for patch releases. Note that we 121*d9f75844SAndroid Build Coastguard Worker # only use the last two digits of the year and the month because the 122*d9f75844SAndroid Build Coastguard Worker # MacOS linker requires the first part of the SOVERSION to fit into 123*d9f75844SAndroid Build Coastguard Worker # 16 bits. 124*d9f75844SAndroid Build Coastguard Worker # https://www.sicpers.info/2013/03/how-to-version-a-mach-o-library/ 125*d9f75844SAndroid Build Coastguard Worker ReplaceStringsInFile( 126*d9f75844SAndroid Build Coastguard Worker 'CMake/AbseilHelpers.cmake', 127*d9f75844SAndroid Build Coastguard Worker {'SOVERSION 0': 'SOVERSION "{}.0.0"'.format(datestamp[2:6])}) 128*d9f75844SAndroid Build Coastguard Worker StripContentBetweenTags('CMakeLists.txt', '# absl:lts-remove-begin', 129*d9f75844SAndroid Build Coastguard Worker '# absl:lts-remove-end') 130*d9f75844SAndroid Build Coastguard Worker 131*d9f75844SAndroid Build Coastguard Worker 132*d9f75844SAndroid Build Coastguard Workerif __name__ == '__main__': 133*d9f75844SAndroid Build Coastguard Worker main(sys.argv) 134