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