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