1# lint as: python3 2# Copyright 2020 The TensorFlow Authors. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License.. 15# ============================================================================== 16"""Update version code in the repo. 17 18We use a python script rather than GNU tools to avoid cross-platform 19difficulties. 20 21The script takes 3 argument: 22 --src <path> a path pointing to the code repo. 23 --version <version> the new version code. 24 --nightly [default: false] when true, the version code will append a build 25 suffix (e.g. dev20201103) 26 27It should not run by bazel. Use it as a simple python script. 28""" 29 30import argparse 31import datetime 32import os 33import re 34 35SETUP_PY_PATH = "tensorflow_lite_support/tools/pip_package/setup.py" 36 37 38def replace_string_in_line(search, replace, filename): 39 """Replace the string in every line of the file in-place.""" 40 with open(filename, "r") as f: 41 content = f.read() 42 with open(filename, "w") as f: 43 f.write(re.sub(search, replace, content)) 44 45 46def get_current_version(path): 47 """Get the current version code from setup.py.""" 48 for line in open(os.path.join(path, SETUP_PY_PATH)): 49 match = re.search("^_VERSION = '([a-z0-9\\.\\-]+)'", line) 50 if match: 51 return match.group(1) 52 print("Cannot find current version!") 53 return None 54 55 56def update_version(path, current_version, new_version): 57 """Update the version code in the codebase.""" 58 # Update setup.py 59 replace_string_in_line( 60 "_VERSION = '%s'" % current_version, 61 # pep440 requires such a replacement 62 "_VERSION = '%s'" % new_version.replace("-", "."), 63 os.path.join(path, SETUP_PY_PATH)) 64 65 66class CustomTimeZone(datetime.tzinfo): 67 68 def utcoffset(self, dt): 69 return -datetime.timedelta(hours=8) 70 71 def tzname(self, dt): 72 return "UTC-8" 73 74 def dst(self, dt): 75 return datetime.timedelta(0) 76 77 78def remove_build_suffix(version): 79 """Remove build suffix (if exists) from a version.""" 80 if version.find("-dev") >= 0: 81 return version[:version.find("-dev")] 82 if version.find(".dev") >= 0: 83 return version[:version.find(".dev")] 84 if version.find("dev") >= 0: 85 return version[:version.find("dev")] 86 return version 87 88 89def main(): 90 parser = argparse.ArgumentParser(description="Update TFLS version in repo") 91 parser.add_argument( 92 "--src", 93 help="a path pointing to the code repo", 94 required=True, 95 default="") 96 parser.add_argument("--version", help="the new SemVer code", default="") 97 parser.add_argument( 98 "--nightly", 99 help="if true, a build suffix will append to the version code. If " 100 "current version code or the <version> argument provided contains a " 101 "build suffix, the suffix will be replaced with the timestamp", 102 action="store_true") 103 args = parser.parse_args() 104 105 path = args.src 106 current_version = get_current_version(path) 107 if not current_version: 108 return 109 new_version = args.version if args.version else current_version 110 if args.nightly: 111 new_version = remove_build_suffix(new_version) 112 # Use UTC-8 rather than uncertain local time. 113 d = datetime.datetime.now(tz=CustomTimeZone()) 114 new_version += "-dev" + d.strftime("%Y%m%d") 115 print("Updating version from %s to %s" % (current_version, new_version)) 116 update_version(path, current_version, new_version) 117 118 119if __name__ == "__main__": 120 main() 121