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