1 #!/usr/bin/python 2 # Copyright 2017 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 # 17 # Automatically copy TensorFlow binaries 18 # 19 # Usage: 20 # ./tensorflow/tools/ci_build/copy_binary.py --filename 21 # tf_nightly/tf_nightly_gpu-1.4.0.dev20170914-cp35-cp35m-manylinux1_x86_64.whl 22 # --new_py_ver 36 23 # 24 """Copy binaries of TensorFlow for different python versions.""" 25 26 # pylint: disable=superfluous-parens 27 28 import argparse 29 import os 30 import re 31 import shutil 32 import tempfile 33 import zipfile 34 35 TF_NIGHTLY_REGEX = (r"(.+)(tf_nightly.*)-(\d\.[\d]{1,2}" 36 r"\.\d.dev[\d]{0,8})-(.+)\.whl") 37 BINARY_STRING_TEMPLATE = "%s-%s-%s.whl" 38 39 40 def check_existence(filename): 41 """Check the existence of file or dir.""" 42 if not os.path.exists(filename): 43 raise RuntimeError("%s not found." % filename) 44 45 46 def copy_binary(directory, origin_tag, new_tag, version, package): 47 """Rename and copy binaries for different python versions. 48 49 Arguments: 50 directory: string of directory 51 origin_tag: str of the old python version tag 52 new_tag: str of the new tag 53 version: the version of the package 54 package: str, name of the package 55 56 """ 57 print("Rename and copy binaries with %s to %s." % (origin_tag, new_tag)) 58 origin_binary = BINARY_STRING_TEMPLATE % (package, version, origin_tag) 59 new_binary = BINARY_STRING_TEMPLATE % (package, version, new_tag) 60 zip_ref = zipfile.ZipFile(os.path.join(directory, origin_binary), "r") 61 62 try: 63 tmpdir = tempfile.mkdtemp() 64 os.chdir(tmpdir) 65 66 zip_ref.extractall() 67 zip_ref.close() 68 old_py_ver = re.search(r"(cp\d\d-cp\d\d)", origin_tag).group(1) 69 new_py_ver = re.search(r"(cp\d\d-cp\d\d)", new_tag).group(1) 70 71 wheel_file = os.path.join( 72 tmpdir, "%s-%s.dist-info" % (package, version), "WHEEL") 73 with open(wheel_file, "r") as f: 74 content = f.read() 75 with open(wheel_file, "w") as f: 76 f.write(content.replace(old_py_ver, new_py_ver)) 77 78 zout = zipfile.ZipFile(directory + new_binary, "w", zipfile.ZIP_DEFLATED) 79 zip_these_files = [ 80 "%s-%s.dist-info" % (package, version), 81 "%s-%s.data" % (package, version), 82 ] 83 for dirname in zip_these_files: 84 for root, _, files in os.walk(dirname): 85 for filename in files: 86 zout.write(os.path.join(root, filename)) 87 zout.close() 88 finally: 89 shutil.rmtree(tmpdir) 90 91 92 def main(): 93 """This script copies binaries. 94 95 Requirements: 96 filename: The path to the whl file 97 AND 98 new_py_ver: Create a nightly tag with current date 99 100 Raises: 101 RuntimeError: If the whl file was not found 102 """ 103 104 parser = argparse.ArgumentParser(description="Cherry picking automation.") 105 106 # Arg information 107 parser.add_argument( 108 "--filename", help="path to whl file we are copying", required=True) 109 parser.add_argument( 110 "--new_py_ver", help="two digit py version eg. 27 or 33", required=True) 111 112 args = parser.parse_args() 113 114 # Argument checking 115 args.filename = os.path.abspath(args.filename) 116 check_existence(args.filename) 117 regex_groups = re.search(TF_NIGHTLY_REGEX, args.filename) 118 directory = regex_groups.group(1) 119 package = regex_groups.group(2) 120 version = regex_groups.group(3) 121 origin_tag = regex_groups.group(4) 122 old_py_ver = re.search(r"(cp\d\d)", origin_tag).group(1) 123 124 # Create new tags 125 new_tag = origin_tag.replace(old_py_ver, "cp" + args.new_py_ver) 126 127 # Copy the binary with the info we have 128 copy_binary(directory, origin_tag, new_tag, version, package) 129 130 131 if __name__ == "__main__": 132 main() 133