17f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#!/usr/bin/python
27f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
37f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#
47f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# Licensed under the Apache License, Version 2.0 (the "License");
57f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# you may not use this file except in compliance with the License.
67f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# You may obtain a copy of the License at
77f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#
87f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#     http://www.apache.org/licenses/LICENSE-2.0
97f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#
107f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# Unless required by applicable law or agreed to in writing, software
117f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# distributed under the License is distributed on an "AS IS" BASIS,
127f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# See the License for the specific language governing permissions and
147f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# limitations under the License.
157f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# ==============================================================================
167f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#
177f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# Automatically copy TensorFlow binaries
187f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#
197f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# Usage:
207f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#           ./tensorflow/tools/ci_build/copy_binary.py --filename
217f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# tf_nightly/tf_nightly_gpu-1.4.0.dev20170914-cp35-cp35m-manylinux1_x86_64.whl
227f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# --new_py_ver 36
237f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar#
247f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar"""Copy binaries of TensorFlow for different python versions."""
257f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
267f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar# pylint: disable=superfluous-parens
277f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
287f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarimport argparse
297f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarimport os
307f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarimport re
317f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarimport shutil
327f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarimport subprocess
337f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarimport zipfile
347f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
357f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit PatankarUNZIP_CMD = "/usr/bin/unzip"
367f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit PatankarZIP_CMD = "/usr/bin/zip"
377f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit PatankarSED_CMD = "/bin/sed"
387f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
397f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit PatankarTF_NIGHTLY_REGEX = r"(.+)tf_nightly(|_gpu)-(\d\.\d\.\d.dev[\d]{0,8})-(.+)\.whl"
407f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit PatankarBINARY_STRING_TEMPLATE = "%s-%s-%s.whl"
417f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
427f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
437f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankardef check_existence(filename):
447f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  """Check the existence of file or dir."""
457f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  if not os.path.exists(filename):
467f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    raise RuntimeError("%s not found.")
477f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
487f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
497f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankardef copy_binary(directory, origin_tag, new_tag, version, gpu=False):
507f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  """Rename and copy binaries for different python versions.
517f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
527f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  Arguments:
537f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    directory: string of directory
547f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    origin_tag: str of the old python version tag
557f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    new_tag: str of the new tag
567f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    version: the version of the package
577f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    gpu: bool if its a gpu build or not
587f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
597f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  """
607f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  print("Rename and copy binaries with %s to %s." % (origin_tag, new_tag))
617f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  if gpu:
627f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    package = "tf_nightly_gpu"
637f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  else:
647f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    package = "tf_nightly"
657f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  origin_binary = BINARY_STRING_TEMPLATE % (package, version, origin_tag)
667f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  new_binary = BINARY_STRING_TEMPLATE % (package, version, new_tag)
677f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  zip_ref = zipfile.ZipFile(directory + origin_binary, "r")
687f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  zip_ref.extractall()
697f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  zip_ref.close()
707f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  old_py_ver = re.search(r"(cp\d\d-cp\d\d)", origin_tag).group(1)
717f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  new_py_ver = re.search(r"(cp\d\d-cp\d\d)", new_tag).group(1)
727f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  subprocess.check_call(
737f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      "%s -i s/%s/%s/g %s-%s.dist-info/WHEEL" % (SED_CMD, old_py_ver,
747f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar                                                 new_py_ver, package, version),
757f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      shell=True)
767f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  zout = zipfile.ZipFile(directory + new_binary, "w", zipfile.ZIP_DEFLATED)
777f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  zip_these_files = [
787f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      "%s-%s.dist-info" % (package, version),
797f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      "%s-%s.data" % (package, version)
807f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  ]
817f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  for dirname in zip_these_files:
827f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    for root, _, files in os.walk(dirname):
837f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      for filename in files:
847f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar        zout.write(os.path.join(root, filename))
857f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  zout.close()
867f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  for dirname in zip_these_files:
877f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    shutil.rmtree(dirname)
887f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
897f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
907f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankardef main():
917f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  """This script copies binaries.
927f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
937f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  Requirements:
947f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    filename: The path to the whl file
957f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    AND
967f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    new_py_ver: Create a nightly tag with current date
977f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
987f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  Raises:
997f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar    RuntimeError: If the whl file was not found
1007f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  """
1017f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1027f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  parser = argparse.ArgumentParser(description="Cherry picking automation.")
1037f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1047f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  # Arg information
1057f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  parser.add_argument(
1067f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      "--filename", help="path to whl file we are copying", required=True)
1077f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  parser.add_argument(
1087f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar      "--new_py_ver", help="two digit py version eg. 27 or 33", required=True)
1097f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1107f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  args = parser.parse_args()
1117f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1127f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  # Argument checking
1137f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  check_existence(args.filename)
1147f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  regex_groups = re.search(TF_NIGHTLY_REGEX, args.filename)
1157f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  directory = regex_groups.group(1)
1167f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  gpu = regex_groups.group(2)
1177f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  version = regex_groups.group(3)
1187f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  origin_tag = regex_groups.group(4)
1197f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  old_py_ver = re.search(r"(cp\d\d)", origin_tag).group(1)
1207f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1217f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  # Create new tags
1227f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  new_tag = origin_tag.replace(old_py_ver, "cp" + args.new_py_ver)
1237f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1247f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  # Copy the binary with the info we have
1257f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  copy_binary(directory, origin_tag, new_tag, version, gpu)
1267f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1277f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar
1287f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankarif __name__ == "__main__":
1297f56f6c62d3bb56bb1f0d89de776c16b2740c645Amit Patankar  main()
130